1 About this primer

Ever since the first genome-wide association study (GWAS) on age-related macular degeneration, and the promise of personalized medicine in the wake of the Human Genome Project, large-scale genetic association studies hold significant sway in contemporary health research and drive drug-development pipelines. In the past 2 decades, researchers delved into GWAS, aiming to unveil genetic variations linked to both human traits, such as the color of your eyes, and rare and common complex diseases. These findings serve as crucial keys to unravel the intricate mechanisms underlying diseases, shedding light on whether the correlations identified in observational studies between risk factors and diseases are truly causal.

These studies have ushered in an exciting era where many researchers thrive on developing new methods and bioinformatic tools to parse ever-growing large datasets collected large population-based biobanks. However, the analyses of these data are challenging and it can be daunting to see the forest for tree among the many tools and their various functions. Enter A Practical Primer in Human Complex Genetics. This GitBook was originally written back in 2022 for the Genetic Epidemiology course organized by the Master Epidemiology of Utrecht University. This practical guide will teach you how to design a GWAS, perform quality control (QC), execute the actual analyses, annotate the GWAS results, and perform further downstream post-GWAS analyses. Throughout the book you’ll work with ‘dummy’, that is fake, data, but in the end, we will use real-world data from the first release of the Welcome Trust Case-Control Consortium (WTCCC) focusing on coronary artery disease (CAD).

A major component of modern-day GWAS is genetic imputation, but for practical reasons it is not part of this book. However, I will provide some pointers as to how to go about do this with minimal coding or scripting experience. Likewise, the courses does not cover the aspects of meta-analyses of GWAS, but some excellent resources exist to which I will direct. As this practical primer evolves, these and other topics may find their place in this book. I should also point out that emphasis of this book is on it being a practical primer. It is intended to provide some practical guidance to doing GWAS, and while theory is important, I will not cover this. Again, some very useful and excellent work exists to which I will point you, but I really want you to learn - and understand the theory - by doing.

So, although originally crafted as a companion for the course, this practical guide stands on its own as a comprehensive resource for diving into all facets of doing a GWAS — save for experimental follow-up, of course 😉.

I can imagine this seems overwhelming, but trust me, you’ll be okay. Just follow this practical. You’ll learn by doing and at the end of the day, you can execute a GWAS independently.

Ready to start?

2 Some background reading

Standing on the shoulders of giants, that’s what this book and I do. I want to acknowledge some great work that has helped me tremendously and, really, this book wouldn’t exist without this awesome work. So, I do want to give you some background reading. Is it a prerequisite? No, not really. For starters, the course covers most and you’ll learn as you go. And if you didn’t come here through the course, you’ll be fine just the same. That said, it’s a always good idea to get familiar with these works as you move forward on your path towards your first GWAS - in fact, I had these printed out with markings and writings all over them as I executed my first GWAS, and they’ve been great as a reference many times after.

Large parts of this work are based on four awesome Nature Protocols from the Zondervan group at the Wellcome Center Human Genetics.

  1. Zondervan KT et al. Designing candidate gene and genome-wide case-control association studies. Nat Protoc 2007.
  2. Pettersson FH et al. Marker selection for genetic case-control association studies. Nat Protoc 2009.
  3. Anderson CA et al. Data QC in genetic case-control association studies. Nat Protoc 2010.
  4. Clarke GM et al. Basic statistical analysis in genetic case-control studies. Nat Protoc 2011.

An update on the community standards of QC for GWAS can be found here:

  1. Laurie CC et al. Quality control and quality assurance in genotypic data for genome-wide association studies. Genet Epidemiol 2010.

With respect to imputation and meta-analyses of GWAS you should also get familiar with the following two works:

  1. Marchini, J. and Howie, B. Genotype imputation for genome-wide association studies. Nat Rev Genet 2010
  2. de Bakker PIW et al. Practical aspects of imputation-driven meta-analysis of genome-wide association studies. Hum Mol Genet 2008.
  3. Winkler TW et al. Quality control and conduct of genome-wide association meta-analyses. Nat Protoc 2014.

Are you ready?

Are you ready? Did you bring coffee and a good dose of energy? Let’s start! Your first point of action is to prepare your system for this course in Chapter 3.

3 Getting started

[THIS CHAPTER NEEDS WORK]

  • introduction
  • briefly touch on operating system
  • split CoCalc vs standalone
    • CoCalc: everything is installed
    • standalone:
      • focus on macOS
      • what to install
      • show how to navigate on macOS Terminal [Some introductory text]

3.1 Your computer

Before getting started, we need to discuss your computer. Most programs made to execute genetic epidemiology studies are developed for the Unix environment, for example Linux and macOS. So, they may not work as intended in a Windows environment. Windows does allow users to install a linux subsystem within Windows 10+ and you can find the detail guide here.

However, I highly recommend one of two options.

  • One, install a linux subsystem on your Windows computer (for example a virtual machine with Ubuntu could work).
  • Two, switch to macOS in combination with homebrew. This will give you all the flexibility to use Unix-based programs for your genetic epidemiology work and at the same time you’ll keep the advantage of a powerful computer with a user-friendly interface.

I chose the latter.

For this practical every command is intended for Linux/macOS, in other words Unix-systems.

3.2 CoCalc vs. Standalone

For the purpose of this practical primer there are one of two steps you need to take to get started. When you are following the course, you will want to read the section CoCalc. When you want to use this book as a standalone, you should check out the instructions in section Standalone - this is probably also the section you want to follow for real-world cases.

But first, I’ll briefly provide some background on the various programs that are commonly used.

3.3 The programs we use

We’ll use a few programs throughout this practical. You’ll probably need these for your (future) genetic epidemiology work too (Table 3.1).

Table 3.1: Programs needed for genetic epidemiology.

Program

Link

Description

PLINK

https://www.cog-genomics.org/plink2/

PLINK is a free, open-source genetic analysis tool set, designed to perform a range of basic data parsing and quality control, as well as basic and large-scale analyses in a computationally efficient manner.

R

https://cran.r-project.org/

A program to perform statistical analysis and visualizations.

RStudio

https://www.rstudio.com

A user-friendly R-wrap-around for code editing, debugging, analyses, and visualization.

Homebrew

https://brew.sh

A great extension for Mac-users to install really useful programs that Apple didn't.

3.3.1 RStudio

RStudio is a very user-friendly interface around R that makes your R-scripting-life a lot easier. You should get used to that. RStudio comes with R so you don’t have to worry about that.

3.3.4 Other programs

Mendelian randomization can be done either with the SMR or GSMR function from GCTA, or with R-packages, like TwoSampleMR.

3.4 CoCalc

[ TEXT NEEDS UPDATING]

Now, pay attention. If you came here through the course Genetic Epidemiology, you don’t have to do anything. All the data you need are already downloaded.

However, when you are using this book as a standalone, you’ll need to start by downloading the data you need for this practical to your Desktop.

For the course we set up a CoCalc Server and everything should be fine; we installed everything you need.

3.5 Standalone

So, you plan to use this book as ‘Standalone’ on a macOS environment. This means you’ll need to install a few things first.

3.5.1 The data you need

You’ll need to start by downloading the data you need for this practical to your Desktop.

Here’s the link to the data.

Link to Google Drive with data

Make sure you put the data in the ~/Desktop/practical/ folder.

The data are pretty large (approx. 15Gb), so this will take a minute or two depending on your internet connection. Time to stretch your legs or grab a coffee (data scientists don’t drink tea).

3.5.2 Terminal

For all the programs we use, except RStudio, you will need the Terminal. This comes with every major operating system; on Windows it is called ‘PowerShell’, but let’s not go there. And regardless, you will (have to start to) make your own scripts. The benefit of using scripts is that each step in your workflow is clearly stipulated and annotated, and it allows for greater reproducibility, easier troubleshooting, and scaling up to high-performance computer clusters.

Open the Terminal, it should be on the left in the toolbar as a little black computer-monitor-like icon. Mac users can type command + space and type terminal, a Terminal screen should open.

From now on we will use little code blocks like the example to indicate a code you should type/copy-paste and hit enter. If a code is followed by a comment, it is indicated by a # - you don’t need to copy-paste and execute this.

CODE BLOCK

CODE BLOCK # some comment here

3.5.4 Installing the software

3.5.4.1 brew

Linux has a great package-manager that is lacking on macOS. You can install brew to compensate for this. This adds the ability to install almost any Linux-based program through the Terminal such as wget, llvm, etc.

Open Terminal and execute the following:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Check if everything is in order.

brew doctor

It shouldn’t report any errors.

3.5.4.3 Installing R and RStudio

Let’s go ahead and use brew to install the R and RStudio software.

In Terminal execute the following and just follow the instructions.

brew install rstudio
brew install --cask r

Now close the terminal window - really make sure that the terminal-program has quit.

Open your fresh installation of RStudio by double clicking the icon. You should be seeing something like figure 3.3

RStudio screenshot.

Figure 3.3: RStudio screenshot.

In the top right, you see a little green-white plus-sign, click this and select ‘R Notebook’ (Figure 3.4).

RStudio screenshot.

Figure 3.4: RStudio screenshot.

You will create an untitled (Untitled1) R notebook: you can combine text descriptions, like you would in a lab-journal, with code-sections. Read what is in the notebook to get a grasp on that (Figure 3.5).

RStudio screenshot.

Figure 3.5: RStudio screenshot.

Right, you should be installing some packages. To do so, you can remove plot(cars) (or leave and create a new code-block as per instructions in the notebook), and copy paste the code below. Make sure to put in a code block like the example in which plot(cars) is in.

remotes::install_github(c("rstudio/rmarkdown"))

install.packages(c("formatR", "remotes", 
                   "httr", "usethis", 
                   "data.table", "devtools", 
                   "dplyr", "tibble", "tidyverse", 
                   "openxlsx",
                   "ggplot2",
                   "ggsci", "ggthemes",
                   "qqman", "CMplot", "plotly", 
                   "openxlsx"))
devtools::install_github("kassambara/ggpubr")

devtools::install_github("oliviasabik/RACER")

remotes::install_github("MRCIEU/TwoSampleMR")
devtools::install_github("MRCIEU/MRInstruments")

if (!require("BiocManager", quietly = TRUE))
  install.packages("BiocManager")
BiocManager::install("geneplotter")

You should load these packages too.

library(rmarkdown)
library(formatR)

library(openxlsx)

library(data.table)

library(tibble)
library(tidyverse)
library(dplyr)
library(plotly)

library(ggplot2)
library(devtools)
library(ggpubr)
library(ggsci)
library(ggthemes)

library(qqman)
library(CMplot)
library(RACER)

library(remotes)
library(TwoSampleMR)
library(MRInstruments)

library("geneplotter")

All in all this may take some time, good moment to relax, review your notes, stretch your legs, or take a coffee.

3.6 Are you ready?

Are you ready? Did you bring coffee and a good dose of energy? Let’s start!

Oh, one more thing: you can save your notebook, the one you just created, to keep all the R codes you are applying in the next chapters and add descriptions and notes. If you save this notebook you’ll notice that a html-file is created. This file is a legible webbrowser-friendly version of your work and contains the codes and the output (code messages, tables, and figures). And the nice thing is, that you can easily share it with others over email.

Ok. ’Nough said, let’s move on to cover some basics in Chapter ??.

4 Licenses and disclaimers

4.2 Disclaimer

The content contained herein is provided only for educational and informational purposes or as required by Dutch law. The author attempted to ensure that content is accurate and obtained from reliable sources, but does not represent it to be error-free. The author may add, amend or repeal any text, procedure or regulation, and failure to timely post such changes to this book shall not be construed as a waiver of enforcement. The author does not warrant that any functions on this website or the contents and references herein will be uninterrupted, that defects will be corrected, or that this website or the contents and references will be free from viruses or other harmful components. Any links to third party information on the author’s website are provided as a courtesy and do not constitute an endorsement of those materials or the third party providing them.

4.3 Images and data used

I took the at-most care to use refer to the original works and data sources where needed. Likewise, all the images c.q. figures are either produced specifically for this book, or I took them from Unsplash to brighten up the book. If you feel I made a mistake and your work should be properly referenced, please don’t hesitate to contact me.

These are the images from Unsplash listed here in no particular order.

5 Colophon

The 2022 and 2024 editions of this book were produce in RStudio and with the bookdown package. Below a listing of installed programs and libraries, the operating system, and their specific versions.

## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value
##  version  R version 4.3.3 (2024-02-29)
##  os       macOS Sonoma 14.5
##  system   x86_64, darwin20
##  ui       X11
##  language (EN)
##  collate  en_US.UTF-8
##  ctype    en_US.UTF-8
##  tz       America/New_York
##  date     2024-04-04
##  pandoc   3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package           * version date (UTC) lib source
##  askpass             1.2.0   2023-09-03 [2] CRAN (R 4.3.0)
##  bookdown          * 0.38.1  2024-03-26 [2] Github (rstudio/bookdown@50a1c1e)
##  bslib               0.6.2   2024-03-22 [2] CRAN (R 4.3.2)
##  cachem              1.0.8   2023-05-01 [2] CRAN (R 4.3.0)
##  chromote            0.2.0   2024-02-12 [1] CRAN (R 4.3.2)
##  cli                 3.6.2   2023-12-11 [2] CRAN (R 4.3.0)
##  colorspace          2.1-0   2023-01-23 [2] CRAN (R 4.3.0)
##  crayon              1.5.2   2022-09-29 [2] CRAN (R 4.3.0)
##  crul                1.4.0   2023-05-17 [2] CRAN (R 4.3.0)
##  curl                5.2.1   2024-03-01 [2] CRAN (R 4.3.2)
##  data.table          1.15.4  2024-03-30 [1] CRAN (R 4.3.2)
##  digest              0.6.35  2024-03-11 [2] CRAN (R 4.3.2)
##  evaluate            0.23    2023-11-01 [2] CRAN (R 4.3.0)
##  fastmap             1.1.1   2023-02-24 [2] CRAN (R 4.3.0)
##  flextable         * 0.9.5   2024-03-06 [1] CRAN (R 4.3.2)
##  fontBitstreamVera   0.1.1   2017-02-01 [2] CRAN (R 4.3.0)
##  fontLiberation      0.1.0   2016-10-15 [2] CRAN (R 4.3.0)
##  fontquiver          0.2.1   2017-02-01 [2] CRAN (R 4.3.0)
##  formatR           * 1.14    2023-01-17 [2] CRAN (R 4.3.0)
##  gdtools             0.3.7   2024-03-05 [2] CRAN (R 4.3.2)
##  gfonts              0.2.0   2023-01-08 [2] CRAN (R 4.3.0)
##  glue                1.7.0   2024-01-09 [2] CRAN (R 4.3.0)
##  htmltools           0.5.8   2024-03-25 [2] CRAN (R 4.3.2)
##  httpcode            0.3.0   2020-04-10 [2] CRAN (R 4.3.0)
##  httpuv              1.6.15  2024-03-26 [2] CRAN (R 4.3.2)
##  jquerylib           0.1.4   2021-04-26 [2] CRAN (R 4.3.0)
##  jsonlite            1.8.8   2023-12-04 [2] CRAN (R 4.3.0)
##  kableExtra        * 1.4.0   2024-01-24 [1] CRAN (R 4.3.2)
##  knitr             * 1.45    2023-10-30 [1] CRAN (R 4.3.0)
##  later               1.3.2   2023-12-06 [2] CRAN (R 4.3.0)
##  lifecycle           1.0.4   2023-11-07 [2] CRAN (R 4.3.0)
##  magrittr            2.0.3   2022-03-30 [2] CRAN (R 4.3.0)
##  mime                0.12    2021-09-28 [2] CRAN (R 4.3.0)
##  munsell             0.5.1   2024-04-01 [1] CRAN (R 4.3.2)
##  officer             0.6.5   2024-02-24 [2] CRAN (R 4.3.2)
##  openssl             2.1.1   2023-09-25 [2] CRAN (R 4.3.0)
##  processx            3.8.4   2024-03-16 [2] CRAN (R 4.3.2)
##  promises            1.2.1   2023-08-10 [2] CRAN (R 4.3.0)
##  ps                  1.7.6   2024-01-18 [2] CRAN (R 4.3.0)
##  R6                  2.5.1   2021-08-19 [2] CRAN (R 4.3.0)
##  ragg                1.3.0   2024-03-13 [2] CRAN (R 4.3.2)
##  Rcpp                1.0.12  2024-01-09 [2] CRAN (R 4.3.0)
##  rlang               1.1.3   2024-01-10 [2] CRAN (R 4.3.0)
##  rmarkdown         * 2.26.1  2024-03-26 [2] Github (rstudio/rmarkdown@ee69d59)
##  rstudioapi          0.16.0  2024-03-24 [2] CRAN (R 4.3.2)
##  sass                0.4.9   2024-03-15 [2] CRAN (R 4.3.2)
##  scales              1.3.0   2023-11-28 [2] CRAN (R 4.3.0)
##  sessioninfo         1.2.2   2021-12-06 [2] CRAN (R 4.3.0)
##  shiny               1.8.1   2024-03-26 [2] CRAN (R 4.3.2)
##  stringi             1.8.3   2023-12-11 [2] CRAN (R 4.3.0)
##  stringr             1.5.1   2023-11-14 [2] CRAN (R 4.3.0)
##  svglite             2.1.3   2023-12-08 [1] CRAN (R 4.3.0)
##  systemfonts         1.0.6   2024-03-07 [2] CRAN (R 4.3.2)
##  textshaping         0.3.7   2023-10-09 [2] CRAN (R 4.3.0)
##  tinytex           * 0.50    2024-03-16 [2] CRAN (R 4.3.2)
##  uuid                1.2-0   2024-01-14 [2] CRAN (R 4.3.0)
##  viridisLite         0.4.2   2023-05-02 [2] CRAN (R 4.3.0)
##  webshot           * 0.5.5   2023-06-26 [1] CRAN (R 4.3.0)
##  webshot2          * 0.1.1   2023-08-11 [1] CRAN (R 4.3.0)
##  websocket           1.4.1   2021-08-18 [1] CRAN (R 4.3.0)
##  xfun                0.43    2024-03-25 [2] CRAN (R 4.3.2)
##  xml2                1.3.6   2023-12-04 [2] CRAN (R 4.3.0)
##  xtable              1.8-4   2019-04-21 [2] CRAN (R 4.3.0)
##  yaml                2.3.8   2023-12-11 [2] CRAN (R 4.3.0)
##  zip                 2.3.1   2024-01-27 [2] CRAN (R 4.3.2)
## 
##  [1] /Users/slaan3/Library/R/x86_64/4.3/library
##  [2] /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library
## 
## ──────────────────────────────────────────────────────────────────────────────

References

LS0tIAp0aXRsZTogIkEgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzIgpzdWJ0aXRsZTogIndpdGggYSB1c2UtY2FzZSBpbiBjYXJkaW92YXNjdWxhciBkaXNlYXNlIgphdXRob3I6ICJbZHIuIFNhbmRlciBXLiB2YW4gZGVyIExhYW5dKGh0dHBzOi8vdmFuZGVybGFhbmFuZC5zY2llbmNlKSBbIVtdKC4vaW1nL19sb2dvL3R3aXR0ZXJfY2lyY2xlX2JsdWUucG5nKXt3aWR0aD0yJX1dKGh0dHBzOi8vd3d3LnR3aXR0ZXIuY29tL3N3dmFuZGVybGFhbikgWyFbXSguL2ltZy9fbG9nby9lbWFpbF9jaXJjbGVfYmx1ZS5wbmcpe3dpZHRoPTIlfV0obWFpbHRvOnMudy52YW5kZXJsYWFuQGdtYWlsLmNvbSkiCmRhdGU6ICJWZXJzaW9uIDIuMC4yICgyMDI0LTA0LTA0KSIKZGVzY3JpcHRpb246ICJUaGlzIGlzIGEgcHJhY3RpY2FsIHByaW1lciBpbiBodW1hbiBjb21wbGV4IGdlbmV0aWNzIHdpdGggYSB1c2UtY2FzZSBpbiBjYXJkaW92YXNjdWxhciBkaXNlYXNlLiBUaGUgb3V0cHV0IGZvcm1hdCBmb3IgdGhpcyBwcmltZXIgaXMgYm9va2Rvd246OmdpdGJvb2suIgpkb2N1bWVudGNsYXNzOiBib29rCmdpdGh1Yi1yZXBvOiBzd3ZhbmRlcmxhYW4vQV9QcmFjdGljYWxfUHJpbWVyX2luX0h1bWFuX0NvbXBsZXhfR2VuZXRpY3MKbGluay1jaXRhdGlvbnM6IHllcwpiaWJsaW9ncmFwaHk6Ci0gYmlibGlvZ3JhcGh5L2Jvb2suYmliCi0gYmlibGlvZ3JhcGh5L3BhY2thZ2VzLmJpYgpiaWJsaW8tc3R5bGU6IGFwYWxpa2UKc2l0ZTogYm9va2Rvd246OmJvb2tkb3duX3NpdGUKYWx3YXlzX2FsbG93X2h0bWw6IHllcwojY292ZXItaW1hZ2U6ICJpbWFnZXMvY292ZXIucG5nIgojYXBwbGUtdG91Y2gtaWNvbjogInRvdWNoLWljb24ucG5nIgojYXBwbGUtdG91Y2gtaWNvbi1zaXplOiAxMjAKI2Zhdmljb246ICJmYXZpY29uLmljbyIKLS0tCgojIEFib3V0IHRoaXMgcHJpbWVyCgpFdmVyIHNpbmNlIHRoZSBmaXJzdCBnZW5vbWUtd2lkZSBhc3NvY2lhdGlvbiBzdHVkeSAoR1dBUykgb24gW2FnZS1yZWxhdGVkIG1hY3VsYXIgZGVnZW5lcmF0aW9uXShodHRwczovL2RvaS5vcmcvMTAuMTEyNi9zY2llbmNlLjExMDk1NTcpe3RhcmdldD0iX2JsYW5rIn0sIGFuZCB0aGUgcHJvbWlzZSBvZiBwZXJzb25hbGl6ZWQgbWVkaWNpbmUgaW4gdGhlIHdha2Ugb2YgdGhlIEh1bWFuIEdlbm9tZSBQcm9qZWN0LCBsYXJnZS1zY2FsZSBnZW5ldGljIGFzc29jaWF0aW9uIHN0dWRpZXMgaG9sZCBzaWduaWZpY2FudCBzd2F5IGluIGNvbnRlbXBvcmFyeSBoZWFsdGggcmVzZWFyY2ggYW5kIFtkcml2ZSBkcnVnLWRldmVsb3BtZW50IHBpcGVsaW5lc10oaHR0cDovL2R4LmRvaS5vcmcvMTAuMTAzOC9ucmQuMjAxNy4yNjIpe3RhcmdldD0iX2JsYW5rIn0uIEluIHRoZSBwYXN0IDIgZGVjYWRlcywgcmVzZWFyY2hlcnMgZGVsdmVkIGludG8gR1dBUywgYWltaW5nIHRvIHVudmVpbCBnZW5ldGljIHZhcmlhdGlvbnMgbGlua2VkIHRvIGJvdGggaHVtYW4gdHJhaXRzLCBzdWNoIGFzIHRoZSBjb2xvciBvZiB5b3VyIGV5ZXMsIGFuZCByYXJlIGFuZCBjb21tb24gY29tcGxleCBkaXNlYXNlcy4gVGhlc2UgZmluZGluZ3Mgc2VydmUgYXMgY3J1Y2lhbCBrZXlzIHRvIHVucmF2ZWwgdGhlIGludHJpY2F0ZSBtZWNoYW5pc21zIHVuZGVybHlpbmcgZGlzZWFzZXMsIHNoZWRkaW5nIGxpZ2h0IG9uIHdoZXRoZXIgdGhlIGNvcnJlbGF0aW9ucyBpZGVudGlmaWVkIGluIG9ic2VydmF0aW9uYWwgc3R1ZGllcyBiZXR3ZWVuIHJpc2sgZmFjdG9ycyBhbmQgZGlzZWFzZXMgYXJlIHRydWx5IGNhdXNhbC4gCgpUaGVzZSBzdHVkaWVzIGhhdmUgdXNoZXJlZCBpbiBhbiBleGNpdGluZyBlcmEgd2hlcmUgbWFueSByZXNlYXJjaGVycyB0aHJpdmUgb24gZGV2ZWxvcGluZyBuZXcgbWV0aG9kcyBhbmQgYmlvaW5mb3JtYXRpYyB0b29scyB0byBwYXJzZSBldmVyLWdyb3dpbmcgbGFyZ2UgZGF0YXNldHMgY29sbGVjdGVkIGxhcmdlIHBvcHVsYXRpb24tYmFzZWQgYmlvYmFua3MuIEhvd2V2ZXIsIHRoZSBhbmFseXNlcyBvZiB0aGVzZSBkYXRhIGFyZSBjaGFsbGVuZ2luZyBhbmQgaXQgY2FuIGJlIGRhdW50aW5nIHRvIHNlZSB0aGUgZm9yZXN0IGZvciB0cmVlIGFtb25nIHRoZSBtYW55IHRvb2xzIGFuZCB0aGVpciB2YXJpb3VzIGZ1bmN0aW9ucy4gRW50ZXIgX0EgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzXy4gVGhpcyBbR2l0Qm9va10oaHR0cHM6Ly9janZhbmxpc3NhLmdpdGh1Yi5pby9naXRib29rLWRlbW8vKXt0YXJnZXQ9Il9ibGFuayJ9IHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYmFjayBpbiAyMDIyIGZvciB0aGUgKipHZW5ldGljIEVwaWRlbWlvbG9neSoqIGNvdXJzZSBvcmdhbml6ZWQgYnkgdGhlIFtNYXN0ZXIgRXBpZGVtaW9sb2d5XShodHRwczovL2VwaWRlbWlvbG9neS1lZHVjYXRpb24ubmwpe3RhcmdldD0iX2JsYW5rIn0gb2YgVXRyZWNodCBVbml2ZXJzaXR5LiBUaGlzIHByYWN0aWNhbCBndWlkZSB3aWxsIHRlYWNoIHlvdSBob3cgdG8gZGVzaWduIGEgR1dBUywgcGVyZm9ybSBxdWFsaXR5IGNvbnRyb2wgKFFDKSwgZXhlY3V0ZSB0aGUgYWN0dWFsIGFuYWx5c2VzLCBhbm5vdGF0ZSB0aGUgR1dBUyByZXN1bHRzLCBhbmQgcGVyZm9ybSBmdXJ0aGVyIGRvd25zdHJlYW0gcG9zdC1HV0FTIGFuYWx5c2VzLiBUaHJvdWdob3V0IHRoZSBib29rIHlvdSdsbCB3b3JrIHdpdGggJ2R1bW15JywgdGhhdCBpcyBmYWtlLCBkYXRhLCBidXQgaW4gdGhlIGVuZCwgd2Ugd2lsbCB1c2UgcmVhbC13b3JsZCBkYXRhIGZyb20gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgdGhlIFsqV2VsY29tZSBUcnVzdCBDYXNlLUNvbnRyb2wgQ29uc29ydGl1bSAoV1RDQ0MpKl0oaHR0cHM6Ly93d3cud3RjY2Mub3JnLnVrL2NjYzEvb3ZlcnZpZXcuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifSBmb2N1c2luZyBvbiBjb3JvbmFyeSBhcnRlcnkgZGlzZWFzZSAoQ0FEKS4gCgpBIG1ham9yIGNvbXBvbmVudCBvZiBtb2Rlcm4tZGF5IEdXQVMgaXMgW2dlbmV0aWMgaW1wdXRhdGlvbl0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9ucmcyNzk2KXt0YXJnZXQ9Il9ibGFuayJ9LCBidXQgZm9yIHByYWN0aWNhbCByZWFzb25zIGl0IGlzIG5vdCBwYXJ0IG9mIHRoaXMgYm9vay4gSG93ZXZlciwgSSB3aWxsIHByb3ZpZGUgc29tZSBwb2ludGVycyBhcyB0byBob3cgdG8gZ28gYWJvdXQgZG8gdGhpcyB3aXRoIG1pbmltYWwgY29kaW5nIG9yIHNjcmlwdGluZyBleHBlcmllbmNlLiBMaWtld2lzZSwgdGhlIGNvdXJzZXMgZG9lcyBub3QgY292ZXIgdGhlIGFzcGVjdHMgb2YgbWV0YS1hbmFseXNlcyBvZiBHV0FTLCBidXQgc29tZSBleGNlbGxlbnQgcmVzb3VyY2VzIGV4aXN0IHRvIHdoaWNoIEkgd2lsbCBkaXJlY3QuIEFzIHRoaXMgcHJhY3RpY2FsIHByaW1lciBldm9sdmVzLCB0aGVzZSBhbmQgb3RoZXIgdG9waWNzIG1heSBmaW5kIHRoZWlyIHBsYWNlIGluIHRoaXMgYm9vay4gCkkgc2hvdWxkIGFsc28gcG9pbnQgb3V0IHRoYXQgZW1waGFzaXMgb2YgdGhpcyBib29rIGlzIG9uIGl0IGJlaW5nIGEgX3ByYWN0aWNhbCBwcmltZXJfLiBJdCBpcyBpbnRlbmRlZCB0byBwcm92aWRlIHNvbWUgcHJhY3RpY2FsIGd1aWRhbmNlIHRvIGRvaW5nIEdXQVMsIGFuZCB3aGlsZSB0aGVvcnkgaXMgaW1wb3J0YW50LCBJIHdpbGwgbm90IGNvdmVyIHRoaXMuIEFnYWluLCBzb21lIHZlcnkgdXNlZnVsIGFuZCBleGNlbGxlbnQgd29yayBleGlzdHMgdG8gd2hpY2ggSSB3aWxsIHBvaW50IHlvdSwgYnV0IEkgcmVhbGx5IHdhbnQgeW91IHRvIGxlYXJuIC0gYW5kIHVuZGVyc3RhbmQgdGhlIHRoZW9yeSAtIGJ5IF9kb2luZ18uIAoKU28sIGFsdGhvdWdoIG9yaWdpbmFsbHkgY3JhZnRlZCBhcyBhIGNvbXBhbmlvbiBmb3IgdGhlIGNvdXJzZSwgdGhpcyBwcmFjdGljYWwgZ3VpZGUgc3RhbmRzIG9uIGl0cyBvd24gYXMgYSBjb21wcmVoZW5zaXZlIHJlc291cmNlIGZvciBkaXZpbmcgaW50byBhbGwgZmFjZXRzIG9mIGRvaW5nIGEgR1dBUyDigJQgc2F2ZSBmb3IgZXhwZXJpbWVudGFsIGZvbGxvdy11cCwgb2YgY291cnNlIPCfmIkuCgpJIGNhbiBpbWFnaW5lIHRoaXMgc2VlbXMgb3ZlcndoZWxtaW5nLCBidXQgdHJ1c3QgbWUsIHlvdSdsbCBiZSBva2F5LiBKdXN0IGZvbGxvdyB0aGlzIHByYWN0aWNhbC4gWW91J2xsIGxlYXJuIGJ5IGRvaW5nIGFuZCBhdCB0aGUgZW5kIG9mIHRoZSBkYXksIHlvdSBjYW4gZXhlY3V0ZSBhIEdXQVMgaW5kZXBlbmRlbnRseS4KCioqUmVhZHkgdG8gc3RhcnQ/KioKCjwhLS0gWW91ciBmaXJzdCBwb2ludCBvZiBhY3Rpb24gaXMgdG8gcHJlcGFyZSB5b3VyIHN5c3RlbSBmb3IgdGhpcyBjb3Vyc2UgaW4gQ2hhcHRlciBcQHJlZihzb21lYmFja2dyb3VuZHJlYWRpbmcpLiAtLT4KCjxzY3JpcHQ+CnRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsKdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkEgUHJhY3RpY2FsIFByaW1lciBpbiBIdW1hbiBDb21wbGV4IEdlbmV0aWNzIj4nICsgdGl0bGUuaW5uZXJIVE1MCjwvc2NyaXB0PgoKPCEtLWNoYXB0ZXI6ZW5kOmluZGV4LlJtZC0tPgoKIyBTb21lIGJhY2tncm91bmQgcmVhZGluZyAgeyNzb21lYmFja2dyb3VuZHJlYWRpbmd9CjwhLS0gIVtdKC4vaW1nL19oZWFkZXJzL3BhcGVyc19vbl93YWxsLnBuZyl7d2lkdGg9MTAwJX0gLS0+CgoKCgoKU3RhbmRpbmcgb24gdGhlIHNob3VsZGVycyBvZiBnaWFudHMsIHRoYXQncyB3aGF0IHRoaXMgYm9vayBhbmQgSSBkby4gSSB3YW50IHRvIGFja25vd2xlZGdlIHNvbWUgZ3JlYXQgd29yayB0aGF0IGhhcyBoZWxwZWQgbWUgdHJlbWVuZG91c2x5IGFuZCwgcmVhbGx5LCB0aGlzIGJvb2sgd291bGRuJ3QgZXhpc3Qgd2l0aG91dCB0aGlzIGF3ZXNvbWUgd29yay4gU28sIEkgZG8gd2FudCB0byBnaXZlIHlvdSBzb21lIGJhY2tncm91bmQgcmVhZGluZy4gSXMgaXQgYSBwcmVyZXF1aXNpdGU/IE5vLCBub3QgcmVhbGx5LiBGb3Igc3RhcnRlcnMsIHRoZSBjb3Vyc2UgY292ZXJzIG1vc3QgYW5kIHlvdSdsbCBsZWFybiBhcyB5b3UgZ28uIEFuZCBpZiB5b3UgZGlkbid0IGNvbWUgaGVyZSB0aHJvdWdoIHRoZSBjb3Vyc2UsIHlvdSdsbCBiZSBmaW5lIGp1c3QgdGhlIHNhbWUuIFRoYXQgc2FpZCwgaXQncyBhIGFsd2F5cyBnb29kIGlkZWEgdG8gZ2V0IGZhbWlsaWFyIHdpdGggdGhlc2Ugd29ya3MgYXMgeW91IG1vdmUgZm9yd2FyZCBvbiB5b3VyIHBhdGggdG93YXJkcyB5b3VyIGZpcnN0IEdXQVMgLSBpbiBmYWN0LCBJIGhhZCB0aGVzZSBwcmludGVkIG91dCB3aXRoIG1hcmtpbmdzIGFuZCB3cml0aW5ncyBhbGwgb3ZlciB0aGVtIGFzIEkgZXhlY3V0ZWQgbXkgZmlyc3QgR1dBUywgYW5kIHRoZXkndmUgYmVlbiBncmVhdCBhcyBhIHJlZmVyZW5jZSBtYW55IHRpbWVzIGFmdGVyLiAKCkxhcmdlIHBhcnRzIG9mIHRoaXMgd29yayBhcmUgYmFzZWQgb24gZm91ciBhd2Vzb21lIE5hdHVyZSBQcm90b2NvbHMgZnJvbSB0aGUgW1pvbmRlcnZhbiBncm91cF0oaHR0cHM6Ly93d3cud2VsbC5veC5hYy51ay9yZXNlYXJjaC9yZXNlYXJjaC1ncm91cHMvem9uZGVydmFuLWdyb3VwKXt0YXJnZXQ9Il9ibGFuayJ9IGF0IHRoZSBXZWxsY29tZSBDZW50ZXIgSHVtYW4gR2VuZXRpY3MuCgoxLiBbWm9uZGVydmFuIEtUIF9ldCBhbC5fICpEZXNpZ25pbmcgY2FuZGlkYXRlIGdlbmUgYW5kIGdlbm9tZS13aWRlIGNhc2UtY29udHJvbCBhc3NvY2lhdGlvbiBzdHVkaWVzLiogTmF0IFByb3RvYyAyMDA3Ll0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMTc5NDc5OTEpe3RhcmdldD0iX2JsYW5rIn0KMi4gW1BldHRlcnNzb24gRkggX2V0IGFsLl8gKk1hcmtlciBzZWxlY3Rpb24gZm9yIGdlbmV0aWMgY2FzZS1jb250cm9sIGFzc29jaWF0aW9uIHN0dWRpZXMuKiBOYXQgUHJvdG9jIDIwMDkuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8xOTM5MDUzMCl7dGFyZ2V0PSJfYmxhbmsifQozLiBbQW5kZXJzb24gQ0EgX2V0IGFsLl8gKkRhdGEgUUMgaW4gZ2VuZXRpYyBjYXNlLWNvbnRyb2wgYXNzb2NpYXRpb24gc3R1ZGllcy4qIE5hdCBQcm90b2MgMjAxMC5dKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcHVibWVkLzIxMDg1MTIyKXt0YXJnZXQ9Il9ibGFuayJ9CjQuIFtDbGFya2UgR00gX2V0IGFsLl8gKkJhc2ljIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGluIGdlbmV0aWMgY2FzZS1jb250cm9sIHN0dWRpZXMuKiBOYXQgUHJvdG9jIDIwMTEuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yMTI5MzQ1Myl7dGFyZ2V0PSJfYmxhbmsifQoKQW4gdXBkYXRlIG9uIHRoZSBjb21tdW5pdHkgc3RhbmRhcmRzIG9mIFFDIGZvciBHV0FTIGNhbiBiZSBmb3VuZCBoZXJlOgoKMS4gW0xhdXJpZSBDQyBfZXQgYWwuXyAqUXVhbGl0eSBjb250cm9sIGFuZCBxdWFsaXR5IGFzc3VyYW5jZSBpbiBnZW5vdHlwaWMgZGF0YSBmb3IgZ2Vub21lLXdpZGUgYXNzb2NpYXRpb24gc3R1ZGllcy4qIEdlbmV0IEVwaWRlbWlvbCAyMDEwLl0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMjA3MTgwNDUpe3RhcmdldD0iX2JsYW5rIn0KCldpdGggcmVzcGVjdCB0byBpbXB1dGF0aW9uIGFuZCBtZXRhLWFuYWx5c2VzIG9mIEdXQVMgeW91IHNob3VsZCBhbHNvIGdldCBmYW1pbGlhciB3aXRoIHRoZSBmb2xsb3dpbmcgdHdvIHdvcmtzOgoKMS4gW01hcmNoaW5pLCBKLiBhbmQgSG93aWUsIEIuICpHZW5vdHlwZSBpbXB1dGF0aW9uIGZvciBnZW5vbWUtd2lkZSBhc3NvY2lhdGlvbiBzdHVkaWVzLiogTmF0IFJldiBHZW5ldCAyMDEwXShodHRwczovL2RvaS5vcmcvMTAuMTAzOC9ucmcyNzk2KXt0YXJnZXQ9Il9ibGFuayJ9CjIuIFtkZSBCYWtrZXIgUElXIF9ldCBhbC5fICpQcmFjdGljYWwgYXNwZWN0cyBvZiBpbXB1dGF0aW9uLWRyaXZlbiBtZXRhLWFuYWx5c2lzIG9mIGdlbm9tZS13aWRlIGFzc29jaWF0aW9uIHN0dWRpZXMuKiBIdW0gTW9sIEdlbmV0IDIwMDguXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8xODg1MjIwMCl7dGFyZ2V0PSJfYmxhbmsifQozLiBbV2lua2xlciBUVyBfZXQgYWwuXyAqUXVhbGl0eSBjb250cm9sIGFuZCBjb25kdWN0IG9mIGdlbm9tZS13aWRlIGFzc29jaWF0aW9uIG1ldGEtYW5hbHlzZXMuKiBOYXQgUHJvdG9jIDIwMTQuXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yNDc2Mjc4Nil7dGFyZ2V0PSJfYmxhbmsifQoKCioqQXJlIHlvdSByZWFkeT8qKgoKQXJlIHlvdSByZWFkeT8gRGlkIHlvdSBicmluZyBjb2ZmZWUgYW5kIGEgZ29vZCBkb3NlIG9mIGVuZXJneT8gTGV0J3Mgc3RhcnQhIFlvdXIgZmlyc3QgcG9pbnQgb2YgYWN0aW9uIGlzIHRvIHByZXBhcmUgeW91ciBzeXN0ZW0gZm9yIHRoaXMgY291cnNlIGluIENoYXB0ZXIgXEByZWYoZ2V0dGluZy1zdGFydGVkKS4KCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvcGFwZXJzX29uX3dhbGwucG5nIiBhbHQ9IlNvbWUgYmFja2dyb3VuZCByZWFkaW5nIj4nICsgdGl0bGUuaW5uZXJIVE1MIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS1jaGFwdGVyOmVuZDowMl8xX3NvbWViYWNrZ3JvdW5kcmVhZGluZy5SbWQtLT4KCiMgR2V0dGluZyBzdGFydGVkIHsjZ2V0dGluZy1zdGFydGVkfQo8IS0tICFbXSguL2ltZy9faGVhZGVycy93b21lbl9iZWhpbmRfbWFjYm9vay5wbmcpe3dpZHRoPTEwMCV9IC0tPgoKCgoKCgo+IFtUSElTIENIQVBURVIgTkVFRFMgV09SS10KPgo+IC0gaW50cm9kdWN0aW9uCj4gLSBicmllZmx5IHRvdWNoIG9uIG9wZXJhdGluZyBzeXN0ZW0KPiAtIHNwbGl0IENvQ2FsYyB2cyBzdGFuZGFsb25lCj4gICAtIENvQ2FsYzogZXZlcnl0aGluZyBpcyBpbnN0YWxsZWQKPiAgIC0gc3RhbmRhbG9uZTogCj4gICAgIC0gZm9jdXMgb24gbWFjT1MKPiAgICAgLSB3aGF0IHRvIGluc3RhbGwKPiAgICAgLSBzaG93IGhvdyB0byBuYXZpZ2F0ZSBvbiBtYWNPUyBUZXJtaW5hbAo+IFtTb21lIGludHJvZHVjdG9yeSB0ZXh0XQoKIyMgWW91ciBjb21wdXRlcgoKQmVmb3JlIGdldHRpbmcgc3RhcnRlZCwgd2UgbmVlZCB0byBkaXNjdXNzIHlvdXIgY29tcHV0ZXIuIE1vc3QgcHJvZ3JhbXMgbWFkZSB0byBleGVjdXRlIGdlbmV0aWMgZXBpZGVtaW9sb2d5IHN0dWRpZXMgYXJlIGRldmVsb3BlZCBmb3IgdGhlIFVuaXggZW52aXJvbm1lbnQsIGZvciBleGFtcGxlIExpbnV4IGFuZCBtYWNPUy4gU28sIHRoZXkgbWF5IG5vdCB3b3JrIGFzIGludGVuZGVkIGluIGEgV2luZG93cyBlbnZpcm9ubWVudC4gV2luZG93cyBkb2VzIGFsbG93IHVzZXJzIHRvIGluc3RhbGwgYSBsaW51eCBzdWJzeXN0ZW0gd2l0aGluIFdpbmRvd3MgMTArIGFuZCB5b3UgY2FuIGZpbmQgdGhlIGRldGFpbCBbZ3VpZGVdKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3dpbmRvd3Mvd3NsL2Fib3V0KXt0YXJnZXQ9Il9ibGFuayJ9IGhlcmUuICAKCkhvd2V2ZXIsIEkgaGlnaGx5IHJlY29tbWVuZCBvbmUgb2YgdHdvIG9wdGlvbnMuIAoKLSBPbmUsIGluc3RhbGwgYSBsaW51eCBzdWJzeXN0ZW0gb24geW91ciBXaW5kb3dzIGNvbXB1dGVyIChmb3IgZXhhbXBsZSBbYSB2aXJ0dWFsIG1hY2hpbmUgd2l0aCBVYnVudHUgY291bGQgd29ya10oaHR0cHM6Ly9ibG9nLnN0b3JhZ2VjcmFmdC5jb20vdGhlLWRlYWQtc2ltcGxlLWd1aWRlLXRvLWluc3RhbGxpbmctYS1saW51eC12aXJ0dWFsLW1hY2hpbmUtb24td2luZG93cy8pe3RhcmdldD0iX2JsYW5rIn0pLiAKLSBUd28sIHN3aXRjaCB0byBtYWNPUyBpbiBjb21iaW5hdGlvbiB3aXRoIFtob21lYnJld10oaHR0cHM6Ly9icmV3LnNoKXt0YXJnZXQ9Il9ibGFuayJ9LiBUaGlzIHdpbGwgZ2l2ZSB5b3UgYWxsIHRoZSBmbGV4aWJpbGl0eSB0byB1c2UgVW5peC1iYXNlZCBwcm9ncmFtcyBmb3IgeW91ciBnZW5ldGljIGVwaWRlbWlvbG9neSB3b3JrIGFuZCBhdCB0aGUgc2FtZSB0aW1lIHlvdSdsbCBrZWVwIHRoZSBhZHZhbnRhZ2Ugb2YgYSBwb3dlcmZ1bCBjb21wdXRlciB3aXRoIGEgdXNlci1mcmllbmRseSBpbnRlcmZhY2UuCgpJIGNob3NlIHRoZSBsYXR0ZXIuIAoKPiBGb3IgdGhpcyBwcmFjdGljYWwgZXZlcnkgY29tbWFuZCBpcyBpbnRlbmRlZCBmb3IgTGludXgvbWFjT1MsIGluIG90aGVyIHdvcmRzIFVuaXgtc3lzdGVtcy4KCiMjIENvQ2FsYyB2cy4gU3RhbmRhbG9uZQoKRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgcHJhY3RpY2FsIHByaW1lciB0aGVyZSBhcmUgb25lIG9mIHR3byBzdGVwcyB5b3UgbmVlZCB0byB0YWtlIHRvIGdldCBzdGFydGVkLiBXaGVuIHlvdSBhcmUgZm9sbG93aW5nIHRoZSBjb3Vyc2UsIHlvdSB3aWxsIHdhbnQgdG8gcmVhZCB0aGUgc2VjdGlvbiAqKkNvQ2FsYyoqLiBXaGVuIHlvdSB3YW50IHRvIHVzZSB0aGlzIGJvb2sgYXMgYSBzdGFuZGFsb25lLCB5b3Ugc2hvdWxkIGNoZWNrIG91dCB0aGUgaW5zdHJ1Y3Rpb25zIGluIHNlY3Rpb24gKipTdGFuZGFsb25lKiogLSB0aGlzIGlzIHByb2JhYmx5IGFsc28gdGhlIHNlY3Rpb24geW91IHdhbnQgdG8gZm9sbG93IGZvciByZWFsLXdvcmxkIGNhc2VzLiAKCkJ1dCBmaXJzdCwgSSdsbCBicmllZmx5IHByb3ZpZGUgc29tZSBiYWNrZ3JvdW5kIG9uIHRoZSB2YXJpb3VzIHByb2dyYW1zIHRoYXQgYXJlIGNvbW1vbmx5IHVzZWQuCgojIyBUaGUgcHJvZ3JhbXMgd2UgdXNlCgpXZSdsbCB1c2UgYSBmZXcgcHJvZ3JhbXMgdGhyb3VnaG91dCB0aGlzIHByYWN0aWNhbC4gWW91J2xsIHByb2JhYmx5IG5lZWQgdGhlc2UgZm9yIHlvdXIgKGZ1dHVyZSkgZ2VuZXRpYyBlcGlkZW1pb2xvZ3kgd29yayB0b28gKFRhYmxlIFxAcmVmKHRhYjpwcm9ncmFtcykpLgoKCgoKCmBgYHs9aHRtbH0KPGRpdiBjbGFzcz0idGFid2lkIj48c3R5bGU+LmNsLTI5ZGEwMDI4e30uY2wtMjlkMzQzOGN7Zm9udC1mYW1pbHk6J0hlbHZldGljYSc7Zm9udC1zaXplOjExcHQ7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3R5bGU6bm9ybWFsO3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOnJnYmEoMCwgMCwgMCwgMS4wMCk7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt9LmNsLTI5ZDY1NjEye21hcmdpbjowO3RleHQtYWxpZ246bGVmdDtib3JkZXItYm90dG9tOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXRvcDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7cGFkZGluZy1ib3R0b206NXB0O3BhZGRpbmctdG9wOjVwdDtwYWRkaW5nLWxlZnQ6NXB0O3BhZGRpbmctcmlnaHQ6NXB0O2xpbmUtaGVpZ2h0OiAxO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7fS5jbC0yOWQ2NjkyMnt3aWR0aDowLjkyNGluO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7dmVydGljYWwtYWxpZ246IG1pZGRsZTtib3JkZXItYm90dG9tOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci10b3A6IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkyY3t3aWR0aDoyLjcxNmluO2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7dmVydGljYWwtYWxpZ246IG1pZGRsZTtib3JkZXItYm90dG9tOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci10b3A6IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkyZHt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAxLjVwdCBzb2xpZCByZ2JhKDEwMiwgMTAyLCAxMDIsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7bWFyZ2luLWJvdHRvbTowO21hcmdpbi10b3A6MDttYXJnaW4tbGVmdDowO21hcmdpbi1yaWdodDowO30uY2wtMjlkNjY5MzZ7d2lkdGg6MC45MjRpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci10b3A6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItbGVmdDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1yaWdodDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO21hcmdpbi1ib3R0b206MDttYXJnaW4tdG9wOjA7bWFyZ2luLWxlZnQ6MDttYXJnaW4tcmlnaHQ6MDt9LmNsLTI5ZDY2OTM3e3dpZHRoOjIuNzE2aW47YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO2JvcmRlci1ib3R0b206IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2NjkzOHt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci10b3A6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItbGVmdDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1yaWdodDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO21hcmdpbi1ib3R0b206MDttYXJnaW4tdG9wOjA7bWFyZ2luLWxlZnQ6MDttYXJnaW4tcmlnaHQ6MDt9LmNsLTI5ZDY2OTQwe3dpZHRoOjAuOTI0aW47YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDt2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO2JvcmRlci1ib3R0b206IDEuNXB0IHNvbGlkIHJnYmEoMTAyLCAxMDIsIDEwMiwgMS4wMCk7Ym9yZGVyLXRvcDogMCBzb2xpZCByZ2JhKDAsIDAsIDAsIDEuMDApO2JvcmRlci1sZWZ0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLXJpZ2h0OiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7bWFyZ2luLWJvdHRvbTowO21hcmdpbi10b3A6MDttYXJnaW4tbGVmdDowO21hcmdpbi1yaWdodDowO30uY2wtMjlkNjY5NDF7d2lkdGg6Mi43MTZpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fS5jbC0yOWQ2Njk0Mnt3aWR0aDoxNC4wMDJpbjtiYWNrZ3JvdW5kLWNvbG9yOnRyYW5zcGFyZW50O3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Ym9yZGVyLWJvdHRvbTogMS41cHQgc29saWQgcmdiYSgxMDIsIDEwMiwgMTAyLCAxLjAwKTtib3JkZXItdG9wOiAwIHNvbGlkIHJnYmEoMCwgMCwgMCwgMS4wMCk7Ym9yZGVyLWxlZnQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTtib3JkZXItcmlnaHQ6IDAgc29saWQgcmdiYSgwLCAwLCAwLCAxLjAwKTttYXJnaW4tYm90dG9tOjA7bWFyZ2luLXRvcDowO21hcmdpbi1sZWZ0OjA7bWFyZ2luLXJpZ2h0OjA7fTwvc3R5bGU+PHRhYmxlIGRhdGEtcXVhcnRvLWRpc2FibGUtcHJvY2Vzc2luZz0ndHJ1ZScgY2xhc3M9J2NsLTI5ZGEwMDI4Jz4KCmBgYAoKPGNhcHRpb24gc3R5bGU9ImRpc3BsYXk6dGFibGUtY2FwdGlvbjsiPihcI3RhYjpwcm9ncmFtcyk8c3Bhbj5Qcm9ncmFtcyBuZWVkZWQgZm9yIGdlbmV0aWMgZXBpZGVtaW9sb2d5Ljwvc3Bhbj48L2NhcHRpb24+CgpgYGB7PWh0bWx9Cgo8dGhlYWQ+PHRyIHN0eWxlPSJvdmVyZmxvdy13cmFwOmJyZWFrLXdvcmQ7Ij48dGggY2xhc3M9ImNsLTI5ZDY2OTIyIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+UHJvZ3JhbTwvc3Bhbj48L3A+PC90aD48dGggY2xhc3M9ImNsLTI5ZDY2OTJjIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+TGluazwvc3Bhbj48L3A+PC90aD48dGggY2xhc3M9ImNsLTI5ZDY2OTJkIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+RGVzY3JpcHRpb248L3NwYW4+PC9wPjwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5QTElOSzwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTM3Ij48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+aHR0cHM6Ly93d3cuY29nLWdlbm9taWNzLm9yZy9wbGluazIvPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzgiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5QTElOSyBpcyBhIGZyZWUsIG9wZW4tc291cmNlIGdlbmV0aWMgYW5hbHlzaXMgdG9vbCBzZXQsIGRlc2lnbmVkIHRvIHBlcmZvcm0gYSByYW5nZSBvZiBiYXNpYyBkYXRhIHBhcnNpbmcgYW5kIHF1YWxpdHkgY29udHJvbCwgYXMgd2VsbCBhcyBiYXNpYyBhbmQgbGFyZ2Utc2NhbGUgYW5hbHlzZXMgaW4gYSBjb21wdXRhdGlvbmFsbHkgZWZmaWNpZW50IG1hbm5lci48L3NwYW4+PC9wPjwvdGQ+PC90cj48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5SPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzciPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5odHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy88L3NwYW4+PC9wPjwvdGQ+PHRkIGNsYXNzPSJjbC0yOWQ2NjkzOCI+PHAgY2xhc3M9ImNsLTI5ZDY1NjEyIj48c3BhbiBjbGFzcz0iY2wtMjlkMzQzOGMiPkEgcHJvZ3JhbSB0byBwZXJmb3JtIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9ucy48L3NwYW4+PC9wPjwvdGQ+PC90cj48dHIgc3R5bGU9Im92ZXJmbG93LXdyYXA6YnJlYWstd29yZDsiPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzYiPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5SU3R1ZGlvPC9zcGFuPjwvcD48L3RkPjx0ZCBjbGFzcz0iY2wtMjlkNjY5MzciPjxwIGNsYXNzPSJjbC0yOWQ2NTYxMiI+PHNwYW4gY2xhc3M9ImNsLTI5ZDM0MzhjIj5odHRwczovL3d3dy5yc3R1ZGlvLmNvbTwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTM4Ij48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+QSB1c2VyLWZyaWVuZGx5IFItd3JhcC1hcm91bmQgZm9yIGNvZGUgZWRpdGluZywgZGVidWdnaW5nLCBhbmFseXNlcywgYW5kIHZpc3VhbGl6YXRpb24uPC9zcGFuPjwvcD48L3RkPjwvdHI+PHRyIHN0eWxlPSJvdmVyZmxvdy13cmFwOmJyZWFrLXdvcmQ7Ij48dGQgY2xhc3M9ImNsLTI5ZDY2OTQwIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+SG9tZWJyZXc8L3NwYW4+PC9wPjwvdGQ+PHRkIGNsYXNzPSJjbC0yOWQ2Njk0MSI+PHAgY2xhc3M9ImNsLTI5ZDY1NjEyIj48c3BhbiBjbGFzcz0iY2wtMjlkMzQzOGMiPmh0dHBzOi8vYnJldy5zaDwvc3Bhbj48L3A+PC90ZD48dGQgY2xhc3M9ImNsLTI5ZDY2OTQyIj48cCBjbGFzcz0iY2wtMjlkNjU2MTIiPjxzcGFuIGNsYXNzPSJjbC0yOWQzNDM4YyI+QSBncmVhdCBleHRlbnNpb24gZm9yIE1hYy11c2VycyB0byBpbnN0YWxsIHJlYWxseSB1c2VmdWwgcHJvZ3JhbXMgdGhhdCBBcHBsZSBkaWRuJ3QuPC9zcGFuPjwvcD48L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPjwvZGl2PgpgYGAKCiMjIyBSU3R1ZGlvCioqUlN0dWRpbyoqIGlzIGEgdmVyeSB1c2VyLWZyaWVuZGx5IGludGVyZmFjZSBhcm91bmQgYFJgIHRoYXQgbWFrZXMgeW91ciBgUmAtc2NyaXB0aW5nLWxpZmUgYSBsb3QgZWFzaWVyLiBZb3Ugc2hvdWxkIGdldCB1c2VkIHRvIHRoYXQuICoqUlN0dWRpbyoqIGNvbWVzIHdpdGggYFJgIHNvIHlvdSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHRoYXQuCgojIyMgUExJTksKUmlnaHQsIG9udG8gYFBMSU5LYC4gCgpBbGwgZ2VuZXRpYyBhbmFseXNlcyBjYW4gYmUgZG9uZSBpbiBQTElOSywgZXZlbiBvbiB5b3VyIGxhcHRvcCwgYnV0IHdpdGggbGFyZ2UgZGF0YXNldHMsIGZvciBleGFtcGxlIFtVSyBCaW9iYW5rXShodHRwczovL3d3dy51a2Jpb2JhbmsuYWMudWspe3RhcmdldD0iX2JsYW5rIn0gc2l6ZSwgaXQgaXMgYmV0dGVyIHRvIHN3aXRjaCB0byBhIFtoaWdoLXBlcmZvcm1hbmNlIGNvbXB1dGluZyBjbHVzdGVyIChIUEMpXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9IaWdoLXBlcmZvcm1hbmNlX2NvbXB1dGluZyl7dGFyZ2V0PSJfYmxhbmsifSBsaWtlIHdlIGhhdmUgYXZhaWxhYmxlIGF0IHRoZSBbVXRyZWNodCBTY2llbmNlIFBhcmtdKGh0dHBzOi8vd2lraS5iaW9pbmZvcm1hdGljcy51bWN1dHJlY2h0Lm5sL2Jpbi92aWV3L0hQQy9XZWJIb21lKXt0YXJnZXQ9Il9ibGFuayJ9LiBUaGUgb3JpZ2luYWwgUExJTksgdjEuMDcgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3p6ei5id2guaGFydmFyZC5lZHUvcGxpbmsvaW5kZXguc2h0bWwpe3RhcmdldD0iX2JsYW5rIn0sIGJ1dCBub3dhZGF5cyB3ZSBhcmUgdXNpbmcgYSBuZXdlciwgZmFzdGVyIHZlcnNpb246ICoqUExJTksgdjEuOSoqIHdoaWNoIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly93d3cuY29nLWdlbm9taWNzLm9yZy9wbGluazIpe3RhcmdldD0iX2JsYW5rIn0uIEl0IHN0aWxsIHNheXMgJ1BMSU5LIDEuOTAgYmV0YScgKEZpZ3VyZSBcQHJlZihmaWc6cGxpbmtwcm9ncmFtKSksIGJ1dCB5b3UgY2FuIGNvbnNpZGVyIHRoaXMgdmVyc2lvbiBzdGFibGUgYW5kIHNhdmUgdG8gd29yayB3aXRoLCBidXQgYXMgeW91IGNhbiBzZWUsIHNvbWUgZnVuY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkIGFueW1vcmUuCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL3BsaW5rLnBuZyIgYWx0PSJUaGUgUExJTksgdjEuOSB3ZWJzaXRlLiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpwbGlua3Byb2dyYW0pVGhlIFBMSU5LIHYxLjkgd2Vic2l0ZS48L3A+CjwvZGl2PgoKCiMjIyBBbHRlcm5hdGl2ZXMgdG8gYFBMSU5LYApOb3dhZGF5cywgYSBsb3Qgb2YgcGVvcGxlIGFsc28gdXNlIHByb2dyYW1zIGxpa2UgW1NOUFRFU1RdKHNucHRlc3Qpe3RhcmdldD0iX2JsYW5rIn0sIFtCT0xULUxNTV0oaHR0cHM6Ly9kYXRhLmJyb2FkaW5zdGl0dXRlLm9yZy9hbGtlc2dyb3VwL0JPTFQtTE1NLyl7dGFyZ2V0PSJfYmxhbmsifSwgIFtHQ1RBXShodHRwOi8vY25zZ2Vub21pY3MuY29tL3NvZnR3YXJlL2djdGEvI092ZXJ2aWV3KXt0YXJnZXQ9Il9ibGFuayJ9LCBvciBbcmVnZW5pZV0oaHR0cHM6Ly9yZ2NnaXRodWIuZ2l0aHViLmlvL3JlZ2VuaWUvKXt0YXJnZXQ9Il9ibGFuayJ9IGFzIGFsdGVybmF0aXZlcyB0byBleGVjdXRlIEdXQVMuIFRoZXNlIHByb2dyYW1zIHdlcmUgZGVzaWduZWQgd2l0aCBzcGVjaWZpYyB1c2UtY2FzZXMgaW4gbWluZCwgZm9yIGluc3RhbmNlIHJlYWxseSBsYXJnZSBiaW9iYW5rIGRhdGEgaW5jbHVkaW5nIGh1bmRyZWRzIG9mIHRob3VzYW5kcyBpbmRpdmlkdWFscywgYmV0dGVyIGNvbnRyb2wgZm9yIHBvcHVsYXRpb24gc3RyYXRpZmljYXRpb24sIHRoZSBhYmlsaXR5IHRvIGVzdGltYXRlIHRyYWl0IGhlcml0YWJpbGl0eSBvciBGc3QsIGFuZCBzbyBvbi4KCiMjIyBPdGhlciBwcm9ncmFtcwpNZW5kZWxpYW4gcmFuZG9taXphdGlvbiBjYW4gYmUgZG9uZSBlaXRoZXIgd2l0aCB0aGUgW1NNUl0oaHR0cDovL2Nuc2dlbm9taWNzLmNvbS9zb2Z0d2FyZS9zbXIvI092ZXJ2aWV3KXt0YXJnZXQ9Il9ibGFuayJ9IG9yIFtHU01SXShodHRwOi8vY25zZ2Vub21pY3MuY29tL3NvZnR3YXJlL2dzbXIvKXt0YXJnZXQ9Il9ibGFuayJ9IGZ1bmN0aW9uIGZyb20gR0NUQSwgb3Igd2l0aCBSLXBhY2thZ2VzLCBsaWtlIFtgVHdvU2FtcGxlTVJgXShodHRwczovL21yY2lldS5naXRodWIuaW8vVHdvU2FtcGxlTVIvKXt0YXJnZXQ9Il9ibGFuayJ9LgoKCiMjIENvQ2FsYwoKPiBbIFRFWFQgTkVFRFMgVVBEQVRJTkddCgpOb3csIHBheSBhdHRlbnRpb24uIElmIHlvdSBjYW1lIGhlcmUgdGhyb3VnaCB0aGUgY291cnNlICoqR2VuZXRpYyBFcGlkZW1pb2xvZ3kqKiwgeW91IGRvbid0IGhhdmUgdG8gZG8gYW55dGhpbmcuIEFsbCB0aGUgZGF0YSB5b3UgbmVlZCBhcmUgYWxyZWFkeSBkb3dubG9hZGVkLiAKCkhvd2V2ZXIsIHdoZW4geW91IGFyZSB1c2luZyB0aGlzIGJvb2sgYXMgYSBzdGFuZGFsb25lLCB5b3UnbGwgbmVlZCB0byBzdGFydCBieSBkb3dubG9hZGluZyB0aGUgZGF0YSB5b3UgbmVlZCBmb3IgdGhpcyBwcmFjdGljYWwgdG8geW91ciBEZXNrdG9wLiAKCkZvciB0aGUgY291cnNlIHdlIHNldCB1cCBhIENvQ2FsYyBTZXJ2ZXIgYW5kIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGZpbmU7IHdlIGluc3RhbGxlZCBldmVyeXRoaW5nIHlvdSBuZWVkLiAKCiMjIFN0YW5kYWxvbmUKClNvLCB5b3UgcGxhbiB0byB1c2UgdGhpcyBib29rIGFzICdTdGFuZGFsb25lJyBvbiBhIG1hY09TIGVudmlyb25tZW50LiBUaGlzIG1lYW5zIHlvdSdsbCBuZWVkIHRvIGluc3RhbGwgYSBmZXcgdGhpbmdzIGZpcnN0LgoKIyMjIFRoZSBkYXRhIHlvdSBuZWVkCgpZb3UnbGwgbmVlZCB0byBzdGFydCBieSBkb3dubG9hZGluZyB0aGUgZGF0YSB5b3UgbmVlZCBmb3IgdGhpcyBwcmFjdGljYWwgdG8geW91ciBEZXNrdG9wLiAKCkhlcmUncyB0aGUgbGluayB0byB0aGUgZGF0YS4gCgpbTGluayB0byBHb29nbGUgRHJpdmUgd2l0aCBkYXRhXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZHJpdmUvZm9sZGVycy8xaURMQjF5NTM0RGZnRVpOUENZQnJJajVYN2dfWGxCYmE/dXNwPXNoYXJlX2xpbmspe3RhcmdldD0iX2JsYW5rIn0KCk1ha2Ugc3VyZSB5b3UgcHV0IHRoZSBkYXRhIGluIHRoZSBgfi9EZXNrdG9wL3ByYWN0aWNhbC9gIGZvbGRlci4KClRoZSBkYXRhIGFyZSBwcmV0dHkgbGFyZ2UgKGFwcHJveC4gMTVHYiksIHNvIHRoaXMgd2lsbCB0YWtlIGEgbWludXRlIG9yIHR3byBkZXBlbmRpbmcgb24geW91ciBpbnRlcm5ldCBjb25uZWN0aW9uLiBUaW1lIHRvIHN0cmV0Y2ggeW91ciBsZWdzIG9yIGdyYWIgYSBjb2ZmZWUgKGRhdGEgc2NpZW50aXN0cyBkb24ndCBkcmluayB0ZWEpLiAKCiMjIyBUZXJtaW5hbCAKCkZvciBhbGwgdGhlIHByb2dyYW1zIHdlIHVzZSwgZXhjZXB0ICoqUlN0dWRpbyoqLCB5b3Ugd2lsbCBuZWVkIHRoZSAqKlRlcm1pbmFsKiouIFRoaXMgY29tZXMgd2l0aCBldmVyeSBtYWpvciBvcGVyYXRpbmcgc3lzdGVtOyBvbiBXaW5kb3dzIGl0IGlzIGNhbGxlZCAnUG93ZXJTaGVsbCcsIGJ1dCBsZXQncyBub3QgZ28gdGhlcmUuIEFuZCByZWdhcmRsZXNzLCB5b3Ugd2lsbCAoaGF2ZSB0byBzdGFydCB0bykgbWFrZSB5b3VyIG93biBzY3JpcHRzLiBUaGUgYmVuZWZpdCBvZiB1c2luZyBzY3JpcHRzIGlzIHRoYXQgZWFjaCBzdGVwIGluIHlvdXIgd29ya2Zsb3cgaXMgY2xlYXJseSBzdGlwdWxhdGVkIGFuZCBhbm5vdGF0ZWQsIGFuZCBpdCBhbGxvd3MgZm9yIGdyZWF0ZXIgcmVwcm9kdWNpYmlsaXR5LCBlYXNpZXIgdHJvdWJsZXNob290aW5nLCBhbmQgc2NhbGluZyB1cCB0byBoaWdoLXBlcmZvcm1hbmNlIGNvbXB1dGVyIGNsdXN0ZXJzLgoKT3BlbiB0aGUgKipUZXJtaW5hbCoqLCBpdCBzaG91bGQgYmUgb24gdGhlIGxlZnQgaW4gdGhlIHRvb2xiYXIgYXMgYSBsaXR0bGUgYmxhY2sgY29tcHV0ZXItbW9uaXRvci1saWtlIGljb24uIE1hYyB1c2VycyBjYW4gdHlwZSBgY29tbWFuZCArIHNwYWNlYCBhbmQgdHlwZSBgdGVybWluYWxgLCBhICoqVGVybWluYWwqKiBzY3JlZW4gc2hvdWxkIG9wZW4uCgo+IEZyb20gbm93IG9uIHdlIHdpbGwgdXNlIGxpdHRsZSBjb2RlIGJsb2NrcyBsaWtlIHRoZSBleGFtcGxlIHRvIGluZGljYXRlIGEgY29kZSB5b3Ugc2hvdWxkIHR5cGUvY29weS1wYXN0ZSBhbmQgaGl0IGVudGVyLiBJZiBhIGNvZGUgaXMgZm9sbG93ZWQgYnkgYSBjb21tZW50LCBpdCBpcyBpbmRpY2F0ZWQgYnkgYSAjIC0geW91IGRvbid0IG5lZWQgdG8gY29weS1wYXN0ZSBhbmQgZXhlY3V0ZSB0aGlzLgoKYGBgCkNPREUgQkxPQ0sKCkNPREUgQkxPQ0sgIyBzb21lIGNvbW1lbnQgaGVyZQpgYGAKCiMjIyBOYXZpZ2F0aW5nIHRoZSBUZXJtaW5hbAoKWW91IGNhbiBuYXZpZ2F0ZSBhcm91bmQgdGhlIGNvbXB1dGVyIHRocm91Z2ggdGhlIHRlcm1pbmFsIGJ5IHR5cGluZyBgY2QgPHBhdGg+YDsgYGNkYCBzdGFuZHMgZm9yICJjaGFuZ2UgZGlyZWN0b3J5IiBhbmQgYDxwYXRoPmAgbWVhbnMgInNvbWVfZmlsZV9kaXJlY3RvcnlfeW91X3dhbnRfdG9fZ29fdG8iLgoKClRoaXMgY29tbWFuZCB3aWxsIGJyaW5nIHlvdSB0byB5b3VyIGhvbWUgZGlyZWN0b3J5LgoKYGBgCmNkIH4gCmBgYAoKVGhpcyB3aWxsIGJyaW5nIHlvdSB0byB0aGUgcGFyZW50IGRpcmVjdG9yeSAodXAgb25lIGxldmVsKS4KCmBgYApjZCAuLi8gCmBgYAoKVGhpcyB3aWxsIGJyaW5nIHlvdSB0byB0aGUgWFhYIGRpcmVjdG9yeS4KCmBgYApjZCBYWFggCmBgYAoKCkxldCdzIG5hdmlnYXRlIHRvIHRoZSBmb2xkZXIgeW91IGp1c3QgZG93bmxvYWRlZC4KCmBgYApjZCB+L0Rlc2t0b3AvcHJhY3RpY2FsCmBgYAoKCkxldCdzIGNoZWNrIG91dCB3aGF0IGlzIGluc2lkZSB0aGUgZGlyZWN0b3J5LCBieSBsaXN0aW5nIChgbHNgKSBpdHMgY29udGVudHMuCgpUaGlzIGNvbW1hbmQgc2hvd3MgZmlsZXMgYXMgbGlzdDsgdGhlIGAtbGAgbWFrZXMgaXQgYSB2ZXJ0aWNhbCBsaXN0IGFuZCBhZGRzIG1vcmUgaW5mb3JtYXRpb24sIHlvdSBjYW4gYWxzbyByZW1vdmUgaXQgYW5kIHNpbXBseSB0eXBlIGBsc2AgLSBnbyBvbiwgYW5kIHRyeS4KCmBgYApscyAtbCAKYGBgCgoKVGhpcyBjb21tYW5kIHNob3dzIGZpbGVzIGFzIGxpc3Qgd2l0aCBodW1hbiByZWFkYWJsZSBmb3JtYXQuCgpgYGAKbHMgLWxoIApgYGAKQWRkaW5nIHRoZSBmbGFncyBgLWxoYCB3aWxsIGdldCB5b3UgdGhlIGNvbnRlbnRzIG9mIGEgZGlyZWN0b3J5IGluIGEgbGlzdCAoYC1sYCkgYW5kIG1ha2UgdGhlIHNpemUgJ2h1bWFuLXJlYWRhYmxlJyAoYC1oYCkuCgpBZGRpbmcgYC10YCBzaG93cyB0aGUgZmlsZXMgYXMgbGlzdCBzb3J0ZWQgYnkgdGltZSBlZGl0ZWQuCgpgYGAKbHMgLWx0IApgYGAKCkFkZGluZyBgLVNgIHNob3dzIHRoZSBmaWxlcyBhcyBsaXN0IHNvcnRlZCBieSBzaXplLgoKYGBgCmxzIC1sUyAKYGBgCgpZb3UgY2FuIGFsc28gY291bnQgdGhlIG51bWJlciBvZiBmaWxlcy4gSnVzdCAncGlwZScgdGhlIHJlc3VsdCBmcm9tIGBsc2AgdG8gdGhlIG5leHQgcHJvZ3JhbSBgd2NgICgnd29yZGNvdW50JykgYW5kIGxpc3QgdGhlIG51bWJlciBvZiBsaW5lcywgYC1sYC4gSW4gdGhpcyBjYXNlIGAtbGAgaXMgYSBmbGFnIHVzZWQgYnkgYHdjYCBhbmQgaXQgaGFzIGEgZGlmZmVyZW50IG1lYW5pbmcgdGhhbiBpdCBkb2VzIGZvciBgbHNgLiAKCmBgYApscyB8IHdjIC1sCmBgYAoKQW5kIGlmIHlvdSB3YW50IHRvIGtub3cgYWxsIHRoZSBmdW5jdGlvbiBvZiBhIHByb2dyYW0gc2ltcGx5IHR5cGUgdGhlIGZvbGxvd2luZy4KCmBgYAptYW4gbHMKYGBgCgpUaGlzIHdpbGwgdGFrZSB5b3UgdG8gYSBtYW51YWwgb2YgdGhlIHByb2dyYW0gd2l0aCBhbiBleHRlbnNpdmUgZGVzY3JpcHRpb24gb2YgZWFjaCBmbGFnIChGaWd1cmUgXEByZWYoZmlnOmxzbWFudWFsKSkuCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL2xzX21hbnVhbC5wbmciIGFsdD0iUGFydGlhbCBvdXRwdXQgZnJvbSB0aGUgbHMgbWFudWFsLiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpsc21hbnVhbClQYXJ0aWFsIG91dHB1dCBmcm9tIHRoZSBscyBtYW51YWwuPC9wPgo8L2Rpdj4KCiMjIyBJbnN0YWxsaW5nIHRoZSBzb2Z0d2FyZQoKIyMjIyBicmV3CgpMaW51eCBoYXMgYSBncmVhdCBwYWNrYWdlLW1hbmFnZXIgdGhhdCBpcyBsYWNraW5nIG9uIG1hY09TLiBZb3UgY2FuIGluc3RhbGwgW2BicmV3YF0oaHR0cHM6Ly9icmV3LnNoKXt0YXJnZXQ9Il9ibGFuayJ9IHRvIGNvbXBlbnNhdGUgZm9yIHRoaXMuIFRoaXMgYWRkcyB0aGUgYWJpbGl0eSB0byBpbnN0YWxsIGFsbW9zdCBhbnkgTGludXgtYmFzZWQgcHJvZ3JhbSB0aHJvdWdoIHRoZSAqKlRlcm1pbmFsKiogc3VjaCBhcyBgd2dldGAsIGBsbHZtYCwgZXRjLiAKCk9wZW4gKipUZXJtaW5hbCoqIGFuZCBleGVjdXRlIHRoZSBmb2xsb3dpbmc6CgpgYGAKL2Jpbi9iYXNoIC1jICIkKGN1cmwgLWZzU0wgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0hvbWVicmV3L2luc3RhbGwvSEVBRC9pbnN0YWxsLnNoKSIKYGBgCgpDaGVjayBpZiBldmVyeXRoaW5nIGlzIGluIG9yZGVyLgoKYGBgCmJyZXcgZG9jdG9yCmBgYAoKSXQgc2hvdWxkbid0IHJlcG9ydCBhbnkgZXJyb3JzLgoKIyMjIyBQTElOSwoKRmlyc3QsIHdlJ2xsIGdldCBgUExJTktgLiBOYXZpZ2F0ZSB0byB0aGUgKipQTElOSyB2MS45Kiogd2Vic2l0ZSwgd2hpY2ggY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL3d3dy5jb2ctZ2Vub21pY3Mub3JnL3BsaW5rMil7dGFyZ2V0PSJfYmxhbmsifS4gRG93bmxvYWQgdGhlIG1hY09TICg2NC1iaXQpIHZlcnNpb24gdW5kZXIgJ1N0YWJsZSAoYmV0YSB4LngsIGRheSBtb250aCB5ZWFyKScuIAoKPiBOb3RlOiBBcHBsZSBwcm9kdWNlZCBJbnRlbC1iYXNlZCBjb21wdXRlcnMgZm9yIGEgZmV3IHllYXJzIGJhY2ssIGFuZCBtb3N0IHByb2dyYW1zLCBwYWNrYWdlcywgbGlicmFyaWVzIGFuZCB3aGF0bm90IGFyZSBkZXNpZ25lZCBmb3IgdGhhdC4gU28sIEkgaGlnaGx5IHJlY29tbWVuZCB1c2luZyBzb2Z0d2FyZSBkZXNpZ25lZCBmb3IgdGhhdCBhbmQgYWN0aXZhdGluZyBSb3NldHRhMiBpbiB5b3VyIFRlcm1pbmFsLiBEb24ndCBrbm93IGhvdyB0byBkbyB0aGF0PyBGb2xsb3dpbmcgW3RoZXNlIGluc3RydWN0aW9uc10oaHR0cHM6Ly9zdXBwb3J0LmFwcGxlLmNvbS9lbi11cy8xMDI1Mjcpe3RhcmdldD0iX2JsYW5rIn0uCgpVbnppcCB0aGUgZm9sZGVyIGFuZCBwdXQgYHBsaW5rYCBpbiB0aGUgcHJhY3RpY2FsIGZvbGRlci4gCgpgYGAKbXYgLXYgfi9Eb3dubG9hZHMvcGxpbmtfbWFjXzIwMjMxMjExL3BsaW5rIH4vRGVza3RvcC9wcmFjdGljYWwvcGxpbmsgCmBgYAoKIyMjIyBJbnN0YWxsaW5nIFIgYW5kIFJTdHVkaW8KCkxldCdzIGdvIGFoZWFkIGFuZCB1c2UgYGJyZXdgIHRvIGluc3RhbGwgdGhlIGBSYCBhbmQgKipSU3R1ZGlvKiogc29mdHdhcmUuCgpJbiAqKlRlcm1pbmFsKiogZXhlY3V0ZSB0aGUgZm9sbG93aW5nIGFuZCBqdXN0IGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zLgoKYGBgCmJyZXcgaW5zdGFsbCByc3R1ZGlvCmJyZXcgaW5zdGFsbCAtLWNhc2sgcgpgYGAKCk5vdyBjbG9zZSB0aGUgdGVybWluYWwgd2luZG93IC0gcmVhbGx5IG1ha2Ugc3VyZSB0aGF0IHRoZSB0ZXJtaW5hbC1wcm9ncmFtIGhhcyBxdWl0LgoKT3BlbiB5b3VyIGZyZXNoIGluc3RhbGxhdGlvbiBvZiAqKlJTdHVkaW8qKiBieSBkb3VibGUgY2xpY2tpbmcgdGhlIGljb24uIFlvdSBzaG91bGQgYmUgc2VlaW5nIHNvbWV0aGluZyBsaWtlIGZpZ3VyZSBcQHJlZihmaWc6cnN0dWRpb3NjcmVlbnNob3QpCgo8ZGl2IGNsYXNzPSJmaWd1cmUiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPgo8aW1nIHNyYz0iaW1nL3JzdHVkaW8tc2NyZWVuc2hvdC5wbmciIGFsdD0iUlN0dWRpbyBzY3JlZW5zaG90LiIgd2lkdGg9Ijg1JSIgLz4KPHAgY2xhc3M9ImNhcHRpb24iPihcI2ZpZzpyc3R1ZGlvc2NyZWVuc2hvdClSU3R1ZGlvIHNjcmVlbnNob3QuPC9wPgo8L2Rpdj4KCgpJbiB0aGUgdG9wIHJpZ2h0LCB5b3Ugc2VlIGEgbGl0dGxlIGdyZWVuLXdoaXRlIHBsdXMtc2lnbiwgY2xpY2sgdGhpcyBhbmQgc2VsZWN0ICdSIE5vdGVib29rJyAoRmlndXJlIFxAcmVmKGZpZzpyc3R1ZGlvc2NyZWVuc2hvdGNyZWF0ZW5vdGVib29rKSkuIAoKPGRpdiBjbGFzcz0iZmlndXJlIiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj4KPGltZyBzcmM9ImltZy9yc3R1ZGlvLXNjcmVlbnNob3QtY3JlYXRlLW5vdGVib29rLnBuZyIgYWx0PSJSU3R1ZGlvIHNjcmVlbnNob3QuIiB3aWR0aD0iODUlIiAvPgo8cCBjbGFzcz0iY2FwdGlvbiI+KFwjZmlnOnJzdHVkaW9zY3JlZW5zaG90Y3JlYXRlbm90ZWJvb2spUlN0dWRpbyBzY3JlZW5zaG90LjwvcD4KPC9kaXY+CgpZb3Ugd2lsbCBjcmVhdGUgYW4gdW50aXRsZWQgKGBVbnRpdGxlZDFgKSBgUmAgbm90ZWJvb2s6IHlvdSBjYW4gY29tYmluZSB0ZXh0IGRlc2NyaXB0aW9ucywgbGlrZSB5b3Ugd291bGQgaW4gYSBsYWItam91cm5hbCwgd2l0aCBjb2RlLXNlY3Rpb25zLiBSZWFkIHdoYXQgaXMgaW4gdGhlIG5vdGVib29rIHRvIGdldCBhIGdyYXNwIG9uIHRoYXQgKEZpZ3VyZSBcQHJlZihmaWc6cnN0dWRpb3NjcmVlbnNob3Rub3RlYm9vaykpLiAKCjxkaXYgY2xhc3M9ImZpZ3VyZSIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+CjxpbWcgc3JjPSJpbWcvcnN0dWRpby1zY3JlZW5zaG90LW5vdGVib29rLnBuZyIgYWx0PSJSU3R1ZGlvIHNjcmVlbnNob3QuIiB3aWR0aD0iODUlIiAvPgo8cCBjbGFzcz0iY2FwdGlvbiI+KFwjZmlnOnJzdHVkaW9zY3JlZW5zaG90bm90ZWJvb2spUlN0dWRpbyBzY3JlZW5zaG90LjwvcD4KPC9kaXY+CgpSaWdodCwgeW91IHNob3VsZCBiZSBpbnN0YWxsaW5nIHNvbWUgcGFja2FnZXMuIFRvIGRvIHNvLCB5b3UgY2FuIHJlbW92ZSBgcGxvdChjYXJzKWAgKG9yIGxlYXZlIGFuZCBjcmVhdGUgYSBuZXcgY29kZS1ibG9jayBhcyBwZXIgaW5zdHJ1Y3Rpb25zIGluIHRoZSBub3RlYm9vayksIGFuZCBjb3B5IHBhc3RlIHRoZSBjb2RlIGJlbG93LiBNYWtlIHN1cmUgdG8gcHV0IGluIGEgY29kZSBibG9jayBsaWtlIHRoZSBleGFtcGxlIGluIHdoaWNoIGBwbG90KGNhcnMpYCBpcyBpbi4KCmBgYApyZW1vdGVzOjppbnN0YWxsX2dpdGh1YihjKCJyc3R1ZGlvL3JtYXJrZG93biIpKQoKaW5zdGFsbC5wYWNrYWdlcyhjKCJmb3JtYXRSIiwgInJlbW90ZXMiLCAKICAgICAgICAgICAgICAgICAgICJodHRyIiwgInVzZXRoaXMiLCAKICAgICAgICAgICAgICAgICAgICJkYXRhLnRhYmxlIiwgImRldnRvb2xzIiwgCiAgICAgICAgICAgICAgICAgICAiZHBseXIiLCAidGliYmxlIiwgInRpZHl2ZXJzZSIsIAogICAgICAgICAgICAgICAgICAgIm9wZW54bHN4IiwKICAgICAgICAgICAgICAgICAgICJnZ3Bsb3QyIiwKICAgICAgICAgICAgICAgICAgICJnZ3NjaSIsICJnZ3RoZW1lcyIsCiAgICAgICAgICAgICAgICAgICAicXFtYW4iLCAiQ01wbG90IiwgInBsb3RseSIsIAogICAgICAgICAgICAgICAgICAgIm9wZW54bHN4IikpCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigia2Fzc2FtYmFyYS9nZ3B1YnIiKQoKZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJvbGl2aWFzYWJpay9SQUNFUiIpCgpyZW1vdGVzOjppbnN0YWxsX2dpdGh1YigiTVJDSUVVL1R3b1NhbXBsZU1SIikKZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJNUkNJRVUvTVJJbnN0cnVtZW50cyIpCgppZiAoIXJlcXVpcmUoIkJpb2NNYW5hZ2VyIiwgcXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoIkJpb2NNYW5hZ2VyIikKQmlvY01hbmFnZXI6Omluc3RhbGwoImdlbmVwbG90dGVyIikKYGBgCgpZb3Ugc2hvdWxkIGxvYWQgdGhlc2UgcGFja2FnZXMgdG9vLiAKCmBgYApsaWJyYXJ5KHJtYXJrZG93bikKbGlicmFyeShmb3JtYXRSKQoKbGlicmFyeShvcGVueGxzeCkKCmxpYnJhcnkoZGF0YS50YWJsZSkKCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShwbG90bHkpCgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZGV2dG9vbHMpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGdnc2NpKQpsaWJyYXJ5KGdndGhlbWVzKQoKbGlicmFyeShxcW1hbikKbGlicmFyeShDTXBsb3QpCmxpYnJhcnkoUkFDRVIpCgpsaWJyYXJ5KHJlbW90ZXMpCmxpYnJhcnkoVHdvU2FtcGxlTVIpCmxpYnJhcnkoTVJJbnN0cnVtZW50cykKCmxpYnJhcnkoImdlbmVwbG90dGVyIikKYGBgCgpBbGwgaW4gYWxsIHRoaXMgbWF5IHRha2Ugc29tZSB0aW1lLCBnb29kIG1vbWVudCB0byByZWxheCwgcmV2aWV3IHlvdXIgbm90ZXMsIHN0cmV0Y2ggeW91ciBsZWdzLCBvciB0YWtlIGEgY29mZmVlLgoKCiMjIEFyZSB5b3UgcmVhZHk/CgpBcmUgeW91IHJlYWR5PyBEaWQgeW91IGJyaW5nIGNvZmZlZSBhbmQgYSBnb29kIGRvc2Ugb2YgZW5lcmd5PyBMZXQncyBzdGFydCEgCgpPaCwgb25lIG1vcmUgdGhpbmc6IHlvdSBjYW4gc2F2ZSB5b3VyIG5vdGVib29rLCB0aGUgb25lIHlvdSBqdXN0IGNyZWF0ZWQsIHRvIGtlZXAgYWxsIHRoZSBgUmAgY29kZXMgeW91IGFyZSBhcHBseWluZyBpbiB0aGUgbmV4dCBjaGFwdGVycyBhbmQgYWRkIGRlc2NyaXB0aW9ucyBhbmQgbm90ZXMuIElmIHlvdSBzYXZlIHRoaXMgbm90ZWJvb2sgeW91J2xsIG5vdGljZSB0aGF0IGEgYGh0bWxgLWZpbGUgaXMgY3JlYXRlZC4gVGhpcyBmaWxlIGlzIGEgbGVnaWJsZSB3ZWJicm93c2VyLWZyaWVuZGx5IHZlcnNpb24gb2YgeW91ciB3b3JrIGFuZCBjb250YWlucyB0aGUgY29kZXMgYW5kIHRoZSBvdXRwdXQgKGNvZGUgbWVzc2FnZXMsIHRhYmxlcywgYW5kIGZpZ3VyZXMpLiBBbmQgdGhlIG5pY2UgdGhpbmcgaXMsIHRoYXQgeW91IGNhbiBlYXNpbHkgc2hhcmUgaXQgd2l0aCBvdGhlcnMgb3ZlciBlbWFpbC4gCgpPay4gJ05vdWdoIHNhaWQsIGxldCdzIG1vdmUgb24gdG8gY292ZXIgc29tZSBiYXNpY3MgaW4gQ2hhcHRlciBcQHJlZihnd2FzLWJhc2ljcykuCgo8IS0tIGBgYHtqcywgZWNobyA9IEZBTFNFfSAtLT4KPCEtLSB0aXRsZT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVhZGVyJyk7IC0tPgo8IS0tIHRpdGxlLmlubmVySFRNTCA9ICc8aW1nIHNyYz0iaW1nL19oZWFkZXJzL3dvbWVuX2JlaGluZF9tYWNib29rLnBuZyIgYWx0PSJHZXR0aW5nIHN0YXJ0ZWQiPicgKyB0aXRsZS5pbm5lckhUTUwgLS0+CjwhLS0gYGBgIC0tPgoKPCEtLWNoYXB0ZXI6ZW5kOjAyXzJfZ2V0dGluZ3N0YXJ0ZWQuUm1kLS0+CgojIExpY2Vuc2VzIGFuZCBkaXNjbGFpbWVycyB7I2xpY2Vuc2V9CjwhLS0gIVtdKGltZy9faGVhZGVycy9saWNlbnNlcy5wbmcpe3dpZHRoPTEwMCV9IC0tPgoKCgoKCiMjIENvcHlyaWdodAoKVGhpcyBib29rIGFuZCBhbGwgaXRzIG1hdGVyaWFsICgiY29udGVudCIpIGlzIHByb3RlY3RlZCBieSBjb3B5cmlnaHQgdW5kZXIgRHV0Y2ggQ29weXJpZ2h0IGxhd3MgYW5kIGlzIHRoZSBwcm9wZXJ0eSBvZiB0aGUgYXV0aG9yIG9yIHRoZSBwYXJ0eSBjcmVkaXRlZCBhcyB0aGUgcHJvdmlkZXIgb2YgdGhlIGNvbnRlbnQuIFlvdSBtYXkgbm90IGNvcHksIHJlcHJvZHVjZSwgZGlzdHJpYnV0ZSwgcHVibGlzaCwgZGlzcGxheSwgcGVyZm9ybSwgbW9kaWZ5LCBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcywgdHJhbnNtaXQsIG9yIGluIGFueSB3YXkgZXhwbG9pdCBhbnkgc3VjaCBjb250ZW50LCBub3IgbWF5IHlvdSBkaXN0cmlidXRlIGFueSBwYXJ0IG9mIHRoaXMgY29udGVudCBvdmVyIGFueSBuZXR3b3JrLCBpbmNsdWRpbmcgYSBsb2NhbCBhcmVhIG5ldHdvcmssIHNlbGwgb3Igb2ZmZXIgaXQgZm9yIHNhbGUsIG9yIHVzZSBzdWNoIGNvbnRlbnQgdG8gY29uc3RydWN0IGFueSBraW5kIG9mIGRhdGFiYXNlLiBZb3UgbWF5IG5vdCBhbHRlciBvciByZW1vdmUgYW55IGNvcHlyaWdodCBvciBvdGhlciBub3RpY2UgZnJvbSBjb3BpZXMgb2YgdGhlIGNvbnRlbnQgb24gdGhpcyB3ZWJzaXRlLiBDb3B5aW5nIG9yIHN0b3JpbmcgYW55IGNvbnRlbnQgZXhjZXB0IGFzIHByb3ZpZGVkIGFib3ZlIGlzIGV4cHJlc3NseSBwcm9oaWJpdGVkIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIG9mIHRoZSBhdXRob3Igb3IgdGhlIGNvcHlyaWdodCBob2xkZXIgaWRlbnRpZmllZCBpbiB0aGUgaW5kaXZpZHVhbCBjb250ZW50J3MgY29weXJpZ2h0IG5vdGljZS4gRm9yIHBlcm1pc3Npb24gdG8gdXNlIHRoaXMgY29udGVudCwgcGxlYXNlIGNvbnRhY3QgdGhlIGF1dGhvci4KCiMjIERpc2NsYWltZXIKClRoZSBjb250ZW50IGNvbnRhaW5lZCBoZXJlaW4gaXMgcHJvdmlkZWQgb25seSBmb3IgZWR1Y2F0aW9uYWwgYW5kIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb3IgYXMgcmVxdWlyZWQgYnkgRHV0Y2ggbGF3LiBUaGUgYXV0aG9yIGF0dGVtcHRlZCB0byBlbnN1cmUgdGhhdCBjb250ZW50IGlzIGFjY3VyYXRlIGFuZCBvYnRhaW5lZCBmcm9tIHJlbGlhYmxlIHNvdXJjZXMsIGJ1dCBkb2VzIG5vdCByZXByZXNlbnQgaXQgdG8gYmUgZXJyb3ItZnJlZS4gVGhlIGF1dGhvciBtYXkgYWRkLCBhbWVuZCBvciByZXBlYWwgYW55IHRleHQsIHByb2NlZHVyZSBvciByZWd1bGF0aW9uLCBhbmQgZmFpbHVyZSB0byB0aW1lbHkgcG9zdCBzdWNoIGNoYW5nZXMgdG8gdGhpcyBib29rIHNoYWxsIG5vdCBiZSBjb25zdHJ1ZWQgYXMgYSB3YWl2ZXIgb2YgZW5mb3JjZW1lbnQuIFRoZSBhdXRob3IgZG9lcyBub3Qgd2FycmFudCB0aGF0IGFueSBmdW5jdGlvbnMgb24gdGhpcyB3ZWJzaXRlIG9yIHRoZSBjb250ZW50cyBhbmQgcmVmZXJlbmNlcyBoZXJlaW4gd2lsbCBiZSB1bmludGVycnVwdGVkLCB0aGF0IGRlZmVjdHMgd2lsbCBiZSBjb3JyZWN0ZWQsIG9yIHRoYXQgdGhpcyB3ZWJzaXRlIG9yIHRoZSBjb250ZW50cyBhbmQgcmVmZXJlbmNlcyB3aWxsIGJlIGZyZWUgZnJvbSB2aXJ1c2VzIG9yIG90aGVyIGhhcm1mdWwgY29tcG9uZW50cy4gQW55IGxpbmtzIHRvIHRoaXJkIHBhcnR5IGluZm9ybWF0aW9uIG9uIHRoZSBhdXRob3LigJlzIHdlYnNpdGUgYXJlIHByb3ZpZGVkIGFzIGEgY291cnRlc3kgYW5kIGRvIG5vdCBjb25zdGl0dXRlIGFuIGVuZG9yc2VtZW50IG9mIHRob3NlIG1hdGVyaWFscyBvciB0aGUgdGhpcmQgcGFydHkgcHJvdmlkaW5nIHRoZW0uCgojIyBJbWFnZXMgYW5kIGRhdGEgdXNlZAoKSSB0b29rIHRoZSBhdC1tb3N0IGNhcmUgdG8gdXNlIHJlZmVyIHRvIHRoZSBvcmlnaW5hbCB3b3JrcyBhbmQgZGF0YSBzb3VyY2VzIHdoZXJlIG5lZWRlZC4gTGlrZXdpc2UsIGFsbCB0aGUgaW1hZ2VzIGMucS4gZmlndXJlcyBhcmUgZWl0aGVyIHByb2R1Y2VkIHNwZWNpZmljYWxseSBmb3IgdGhpcyBib29rLCBvciBJIHRvb2sgdGhlbSBmcm9tIFsqKlVuc3BsYXNoKipdKGh0dHBzOi8vdW5zcGxhc2guY29tL3MvcGhvdG9zL2xlZ2FsKSB0byBicmlnaHRlbiB1cCB0aGUgYm9vay4gSWYgeW91IGZlZWwgSSBtYWRlIGEgbWlzdGFrZSBhbmQgeW91ciB3b3JrIHNob3VsZCBiZSBwcm9wZXJseSByZWZlcmVuY2VkLCBwbGVhc2UgZG9uJ3QgaGVzaXRhdGUgdG8gY29udGFjdCBtZS4gCgpUaGVzZSBhcmUgdGhlIGltYWdlcyBmcm9tICoqVW5zcGxhc2gqKiBsaXN0ZWQgaGVyZSBpbiBubyBwYXJ0aWN1bGFyIG9yZGVyLgoKLSBwYXBlcnNfb25fd2FsbCAtIGh0dHBzOi8vdW5zcGxhc2guY29tL3Bob3Rvcy9vcGVuLWJvb2stbG90LU9hcWs3cXFOaF9jCi0gd29tZW5fYmVoaW5kX21hY2Jvb2sgLSBodHRwczovL3Vuc3BsYXNoLmNvbS9waG90b3Mvd29tYW4tdXNpbmctbWFjYm9vay1wcm8td2l0aC1wZXJzb24taW4td2hpdGUtdG9wLWJQVk00bk95MFJnCi0gd29tYW5fd29ya2luZ19vbl9jb2RlIC0gaHR0cHM6Ly91bnNwbGFzaC5jb20vcGhvdG9zL3dvbWFuLXdlYXJpbmctYmxhY2stdC1zaGlydC1ob2xkaW5nLXdoaXRlLWNvbXB1dGVyLWtleWJvYXJkLVlLMEhQd1dESjFJCi0gbGljZW5zZXMgLSBodHRwczovL3Vuc3BsYXNoLmNvbS9waG90b3MvYm9vay1sb3Qtb24tYmxhY2std29vZGVuLXNoZWxmLXplSC1samF3SHRnCgojIyBDb3B5cmlnaHQKCkNvcHlyaWdodCAxOTc5LTIwMjQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFNhbmRlciBXLiB2YW4gZGVyIExhYW4gfCBbcy53LnZhbmRlcmxhYW4gW2F0XSBnbWFpbC5jb21dKG1haWx0bzpzLncudmFuZGVybGFhbkBnbWFpbC5jb20pIHwgW2h0dHBzOi8vdmFuZGVybGFhbmFuZC5zY2llbmNlXShodHRwczovL3ZhbmRlcmxhYW5hbmQuc2NpZW5jZSl7dGFyZ2V0PSJfYmxhbmsifS4gUHVibGlzaGVkIHdpdGggW2Bib29rZG93bmBdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duLyl7dGFyZ2V0PSJfYmxhbmsifS4KCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkxpY2Vuc2VzIj4nICsgdGl0bGUuaW5uZXJIVE1MIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS1jaGFwdGVyOmVuZDoxMV9saWNlbnNlcy5SbWQtLT4KCiMgQ29sb3Bob24KCgoKCgpUaGUgMjAyMiBhbmQgMjAyNCBlZGl0aW9ucyBvZiB0aGlzIGJvb2sgd2VyZSBwcm9kdWNlIGluIFJTdHVkaW8gYW5kIHdpdGggdGhlIGBib29rZG93bmAgcGFja2FnZS4gQmVsb3cgYSBsaXN0aW5nIG9mIGluc3RhbGxlZCBwcm9ncmFtcyBhbmQgbGlicmFyaWVzLCB0aGUgb3BlcmF0aW5nIHN5c3RlbSwgYW5kIHRoZWlyIHNwZWNpZmljIHZlcnNpb25zLgoKCmBgYAojIyDilIAgU2Vzc2lvbiBpbmZvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAojIyAgc2V0dGluZyAgdmFsdWUKIyMgIHZlcnNpb24gIFIgdmVyc2lvbiA0LjMuMyAoMjAyNC0wMi0yOSkKIyMgIG9zICAgICAgIG1hY09TIFNvbm9tYSAxNC41CiMjICBzeXN0ZW0gICB4ODZfNjQsIGRhcndpbjIwCiMjICB1aSAgICAgICBYMTEKIyMgIGxhbmd1YWdlIChFTikKIyMgIGNvbGxhdGUgIGVuX1VTLlVURi04CiMjICBjdHlwZSAgICBlbl9VUy5VVEYtOAojIyAgdHogICAgICAgQW1lcmljYS9OZXdfWW9yawojIyAgZGF0ZSAgICAgMjAyNC0wNC0wNAojIyAgcGFuZG9jICAgMy4xLjEgQCAvQXBwbGljYXRpb25zL1JTdHVkaW8uYXBwL0NvbnRlbnRzL1Jlc291cmNlcy9hcHAvcXVhcnRvL2Jpbi90b29scy8gKHZpYSBybWFya2Rvd24pCiMjIAojIyDilIAgUGFja2FnZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiMjICBwYWNrYWdlICAgICAgICAgICAqIHZlcnNpb24gZGF0ZSAoVVRDKSBsaWIgc291cmNlCiMjICBhc2twYXNzICAgICAgICAgICAgIDEuMi4wICAgMjAyMy0wOS0wMyBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGJvb2tkb3duICAgICAgICAgICogMC4zOC4xICAyMDI0LTAzLTI2IFsyXSBHaXRodWIgKHJzdHVkaW8vYm9va2Rvd25ANTBhMWMxZSkKIyMgIGJzbGliICAgICAgICAgICAgICAgMC42LjIgICAyMDI0LTAzLTIyIFsyXSBDUkFOIChSIDQuMy4yKQojIyAgY2FjaGVtICAgICAgICAgICAgICAxLjAuOCAgIDIwMjMtMDUtMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBjaHJvbW90ZSAgICAgICAgICAgIDAuMi4wICAgMjAyNC0wMi0xMiBbMV0gQ1JBTiAoUiA0LjMuMikKIyMgIGNsaSAgICAgICAgICAgICAgICAgMy42LjIgICAyMDIzLTEyLTExIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgY29sb3JzcGFjZSAgICAgICAgICAyLjEtMCAgIDIwMjMtMDEtMjMgWzJdIENSQU4gKFIgNC4zLjApCiMjICBjcmF5b24gICAgICAgICAgICAgIDEuNS4yICAgMjAyMi0wOS0yOSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGNydWwgICAgICAgICAgICAgICAgMS40LjAgICAyMDIzLTA1LTE3IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgY3VybCAgICAgICAgICAgICAgICA1LjIuMSAgIDIwMjQtMDMtMDEgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBkYXRhLnRhYmxlICAgICAgICAgIDEuMTUuNCAgMjAyNC0wMy0zMCBbMV0gQ1JBTiAoUiA0LjMuMikKIyMgIGRpZ2VzdCAgICAgICAgICAgICAgMC42LjM1ICAyMDI0LTAzLTExIFsyXSBDUkFOIChSIDQuMy4yKQojIyAgZXZhbHVhdGUgICAgICAgICAgICAwLjIzICAgIDIwMjMtMTEtMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBmYXN0bWFwICAgICAgICAgICAgIDEuMS4xICAgMjAyMy0wMi0yNCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGZsZXh0YWJsZSAgICAgICAgICogMC45LjUgICAyMDI0LTAzLTA2IFsxXSBDUkFOIChSIDQuMy4yKQojIyAgZm9udEJpdHN0cmVhbVZlcmEgICAwLjEuMSAgIDIwMTctMDItMDEgWzJdIENSQU4gKFIgNC4zLjApCiMjICBmb250TGliZXJhdGlvbiAgICAgIDAuMS4wICAgMjAxNi0xMC0xNSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGZvbnRxdWl2ZXIgICAgICAgICAgMC4yLjEgICAyMDE3LTAyLTAxIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgZm9ybWF0UiAgICAgICAgICAgKiAxLjE0ICAgIDIwMjMtMDEtMTcgWzJdIENSQU4gKFIgNC4zLjApCiMjICBnZHRvb2xzICAgICAgICAgICAgIDAuMy43ICAgMjAyNC0wMy0wNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIGdmb250cyAgICAgICAgICAgICAgMC4yLjAgICAyMDIzLTAxLTA4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgZ2x1ZSAgICAgICAgICAgICAgICAxLjcuMCAgIDIwMjQtMDEtMDkgWzJdIENSQU4gKFIgNC4zLjApCiMjICBodG1sdG9vbHMgICAgICAgICAgIDAuNS44ICAgMjAyNC0wMy0yNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIGh0dHBjb2RlICAgICAgICAgICAgMC4zLjAgICAyMDIwLTA0LTEwIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgaHR0cHV2ICAgICAgICAgICAgICAxLjYuMTUgIDIwMjQtMDMtMjYgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBqcXVlcnlsaWIgICAgICAgICAgIDAuMS40ICAgMjAyMS0wNC0yNiBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIGpzb25saXRlICAgICAgICAgICAgMS44LjggICAyMDIzLTEyLTA0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAga2FibGVFeHRyYSAgICAgICAgKiAxLjQuMCAgIDIwMjQtMDEtMjQgWzFdIENSQU4gKFIgNC4zLjIpCiMjICBrbml0ciAgICAgICAgICAgICAqIDEuNDUgICAgMjAyMy0xMC0zMCBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIGxhdGVyICAgICAgICAgICAgICAgMS4zLjIgICAyMDIzLTEyLTA2IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgbGlmZWN5Y2xlICAgICAgICAgICAxLjAuNCAgIDIwMjMtMTEtMDcgWzJdIENSQU4gKFIgNC4zLjApCiMjICBtYWdyaXR0ciAgICAgICAgICAgIDIuMC4zICAgMjAyMi0wMy0zMCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIG1pbWUgICAgICAgICAgICAgICAgMC4xMiAgICAyMDIxLTA5LTI4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgbXVuc2VsbCAgICAgICAgICAgICAwLjUuMSAgIDIwMjQtMDQtMDEgWzFdIENSQU4gKFIgNC4zLjIpCiMjICBvZmZpY2VyICAgICAgICAgICAgIDAuNi41ICAgMjAyNC0wMi0yNCBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIG9wZW5zc2wgICAgICAgICAgICAgMi4xLjEgICAyMDIzLTA5LTI1IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgcHJvY2Vzc3ggICAgICAgICAgICAzLjguNCAgIDIwMjQtMDMtMTYgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBwcm9taXNlcyAgICAgICAgICAgIDEuMi4xICAgMjAyMy0wOC0xMCBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIHBzICAgICAgICAgICAgICAgICAgMS43LjYgICAyMDI0LTAxLTE4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgUjYgICAgICAgICAgICAgICAgICAyLjUuMSAgIDIwMjEtMDgtMTkgWzJdIENSQU4gKFIgNC4zLjApCiMjICByYWdnICAgICAgICAgICAgICAgIDEuMy4wICAgMjAyNC0wMy0xMyBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIFJjcHAgICAgICAgICAgICAgICAgMS4wLjEyICAyMDI0LTAxLTA5IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgcmxhbmcgICAgICAgICAgICAgICAxLjEuMyAgIDIwMjQtMDEtMTAgWzJdIENSQU4gKFIgNC4zLjApCiMjICBybWFya2Rvd24gICAgICAgICAqIDIuMjYuMSAgMjAyNC0wMy0yNiBbMl0gR2l0aHViIChyc3R1ZGlvL3JtYXJrZG93bkBlZTY5ZDU5KQojIyAgcnN0dWRpb2FwaSAgICAgICAgICAwLjE2LjAgIDIwMjQtMDMtMjQgWzJdIENSQU4gKFIgNC4zLjIpCiMjICBzYXNzICAgICAgICAgICAgICAgIDAuNC45ICAgMjAyNC0wMy0xNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHNjYWxlcyAgICAgICAgICAgICAgMS4zLjAgICAyMDIzLTExLTI4IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgc2Vzc2lvbmluZm8gICAgICAgICAxLjIuMiAgIDIwMjEtMTItMDYgWzJdIENSQU4gKFIgNC4zLjApCiMjICBzaGlueSAgICAgICAgICAgICAgIDEuOC4xICAgMjAyNC0wMy0yNiBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHN0cmluZ2kgICAgICAgICAgICAgMS44LjMgICAyMDIzLTEyLTExIFsyXSBDUkFOIChSIDQuMy4wKQojIyAgc3RyaW5nciAgICAgICAgICAgICAxLjUuMSAgIDIwMjMtMTEtMTQgWzJdIENSQU4gKFIgNC4zLjApCiMjICBzdmdsaXRlICAgICAgICAgICAgIDIuMS4zICAgMjAyMy0xMi0wOCBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIHN5c3RlbWZvbnRzICAgICAgICAgMS4wLjYgICAyMDI0LTAzLTA3IFsyXSBDUkFOIChSIDQuMy4yKQojIyAgdGV4dHNoYXBpbmcgICAgICAgICAwLjMuNyAgIDIwMjMtMTAtMDkgWzJdIENSQU4gKFIgNC4zLjApCiMjICB0aW55dGV4ICAgICAgICAgICAqIDAuNTAgICAgMjAyNC0wMy0xNiBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHV1aWQgICAgICAgICAgICAgICAgMS4yLTAgICAyMDI0LTAxLTE0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgdmlyaWRpc0xpdGUgICAgICAgICAwLjQuMiAgIDIwMjMtMDUtMDIgWzJdIENSQU4gKFIgNC4zLjApCiMjICB3ZWJzaG90ICAgICAgICAgICAqIDAuNS41ICAgMjAyMy0wNi0yNiBbMV0gQ1JBTiAoUiA0LjMuMCkKIyMgIHdlYnNob3QyICAgICAgICAgICogMC4xLjEgICAyMDIzLTA4LTExIFsxXSBDUkFOIChSIDQuMy4wKQojIyAgd2Vic29ja2V0ICAgICAgICAgICAxLjQuMSAgIDIwMjEtMDgtMTggWzFdIENSQU4gKFIgNC4zLjApCiMjICB4ZnVuICAgICAgICAgICAgICAgIDAuNDMgICAgMjAyNC0wMy0yNSBbMl0gQ1JBTiAoUiA0LjMuMikKIyMgIHhtbDIgICAgICAgICAgICAgICAgMS4zLjYgICAyMDIzLTEyLTA0IFsyXSBDUkFOIChSIDQuMy4wKQojIyAgeHRhYmxlICAgICAgICAgICAgICAxLjgtNCAgIDIwMTktMDQtMjEgWzJdIENSQU4gKFIgNC4zLjApCiMjICB5YW1sICAgICAgICAgICAgICAgIDIuMy44ICAgMjAyMy0xMi0xMSBbMl0gQ1JBTiAoUiA0LjMuMCkKIyMgIHppcCAgICAgICAgICAgICAgICAgMi4zLjEgICAyMDI0LTAxLTI3IFsyXSBDUkFOIChSIDQuMy4yKQojIyAKIyMgIFsxXSAvVXNlcnMvc2xhYW4zL0xpYnJhcnkvUi94ODZfNjQvNC4zL2xpYnJhcnkKIyMgIFsyXSAvTGlicmFyeS9GcmFtZXdvcmtzL1IuZnJhbWV3b3JrL1ZlcnNpb25zLzQuMy14ODZfNjQvUmVzb3VyY2VzL2xpYnJhcnkKIyMgCiMjIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgApgYGAKCjwhLS0gYGBge2pzLCBlY2hvID0gRkFMU0V9IC0tPgo8IS0tIHRpdGxlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKTsgLS0+CjwhLS0gdGl0bGUuaW5uZXJIVE1MID0gJzxpbWcgc3JjPSJpbWcvX2hlYWRlcnMvYmFubmVyX21hbl9zdGFuZGluZ19kbmEucG5nIiBhbHQ9IkNvbG9mb24iPicgKyB0aXRsZS5pbm5lckhUTUwgLS0+CjwhLS0gYGBgIC0tPgoKPCEtLSBleGFtcGxlOiBodHRwczovL3llYXJib29rZGlzY292ZXJpZXMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE0LzA1L1dyaXRpbmdfYV9ZZWFyYm9va19Db2xvcGhvbi5wZGYgLS0+CjwhLS0gU1BFQ0lBTCBUSEFOS1M6IChUaGUgc3RhZmYgd3JvdGUgYSBmZXcgcGFyYWdyYXBocyBhYm91dCB0aGUgeWVhciBhbmQgbWVudGlvbmVkIGEgdmFyaWV0eSAtLT4KPCEtLSBvZiBwZW9wbGUgd2hvIHdlcmUgaW5zdHJ1bWVudGFsIGluIHRoZSBzdWNjZXNzIG9mIHRoZWlyIHllYXJib29rLikgLS0+CjwhLS0gQ09WRVIgJiBFTkRTSEVFVFM6IFRoZSAyMDEzIFBpbm5hY2xlIGNvdmVyIGlzIGEgZm91ci1jb2xvciBsaXRob2dyYXBoLiBBbiBpcmlkZXNjZW50IGZvaWwgLS0+CjwhLS0gY292ZXJzIGEgcG9ydGlvbiBvZiB0aGUgdGhlbWUgZGVzaWduLiBUaGUgZW5kc2hlZXRzIGFyZSBzdGFuZGFyZCBzdG9jayBwYXBlci4gVGhlIHRoZW1lIC0tPgo8IS0tIGNvbmNlcHQgd2FzIGNyZWF0ZWQgYW5kIGV4cGFuZGVkIGJ5IHRoZSBlZGl0b3JpYWwgdGVhbSBhbmQgbWVtYmVycyBvZiB0aGUgMjAxMyBQaW5uYWNsZSAtLT4KPCEtLSBzdGFmZi4gQ292ZXIgYW5kIGVuZHNoZWV0cyB3ZXJlIGRlc2lnbmVkIGJ5IFBpbm5hY2xlIGNvLWVkaXRvcnMtaW4tY2hpZWYgUmVnYW4gQnJvd24gYW5kIC0tPgo8IS0tIEVsbGVuYSBTdWxsaXZhbiwgd2l0aCBpbnNwaXJhdGlvbiBwcm92aWRlZCBieSBhbiBlYXJseSBkZXNpZ24gZnJvbSBjby1yZWZlcmVuY2UgZWRpdG9yIC0tPgo8IS0tIEFtYW5kYSBGYXJyZXIuIC0tPgo8IS0tIFRZUEUgJiBDT0xPUiBUUkVBVE1FTlQ6IEJvZHkgY29weSB0aHJvdWdob3V0IHRoZSBib29rIGlzIHNldCBpbiBGcnV0aWdlciBMaWdodCAtLT4KPCEtLSBDb25kZW5zZWQgKDguNSBwdC4pIENhcHRpb25zIGFyZSBzZXQgaW4gRnJ1dGlnZXIgTGlnaHQgQ29uZGVuc2VkICg3LjUgcHQuKSBIZWFkbGluZSAtLT4KPCEtLSB0cmVhdG1lbnRzIGFyZSBkZXNpZ25lZCB3aXRoIHZhcmlhdGlvbnMgb2YgQUhKIE5hc2h2aWxsZSwgQXJubyBQcm8gYW5kIEZydXRpZ2VyLiBQaG90byAtLT4KPCEtLSBjcmVkaXRzIGFuZCBzcHJlYWQgY3JlZGl0cyBhcHBlYXIgaW4gRnJ1dGlnZXIgSXRhbGljICg2IHB0LikgLS0+CjwhLS0gRm9yIGNvbnNpc3RlbmN5LCBhIGNvbG9yIHBhbGV0dGUgd2FzIGNob3Nlbi4gSW4gYWRkaXRpb24gdG8gdGhlIHRyYWRpdGlvbmFsIGJsYWNrLCB0aGUgLS0+CjwhLS0gZm9sbG93aW5nIGNvbG9ycyBhcHBlYXIgdGhyb3VnaG91dCB0aGUgcHVibGljYXRpb246IFBhbnRvbmUgMTUxQywgUGFudG9uZSAzMDA1QywgUGFudG9uIC0tPgo8IS0tIDI5ODVDLCBQYW50b25lIDExNUMsIFBhbnRvbmUgMzc2QywgUGFudG9uZSAzNjNDLCBQYW50b25lIDI2NkMsIFBhbnRvbmUgMTg1QyBhbmQgLS0+CjwhLS0gUGFudG9uZSBDb29sIEdyZXkgN0MuIC0tPgo8IS0tIFBVQkxJU0hJTkc6IFZvbHVtZSAxMDcgb2YgdGhlIFBpbm5hY2xlIHdhcyBkZXNpZ25lZCBhbmQgcHJvZHVjZWQgYnkgdGhlIDIwMTMgUGlubmFjbGUgLS0+CjwhLS0gc3RhZmYuIFRoZSA0NTYtcGFnZSwgYWxsLWNvbG9yIFBpbm5hY2xlIGlzIHByaW50ZWQgb24gODAgbGIuIGdsb3NzIHBhcGVyIGJ5IEhlcmZmIEpvbmVzIC0tPgo8IS0tIFB1Ymxpc2hpbmcgQ28uIGluIEthbnNhcyBDaXR5LCBNTy4gQXBwcm94aW1hdGVseSAzLDAwMCBjb3BpZXMgd2VyZSBwcmUtb3JkZXJlZCBmb3IgJDUyLiAtLT4KPCEtLSBBbnkgZXh0cmEgY29waWVzIHdlcmUgc29sZCBmb3IgJDYwLiBBIDQ4LXBhZ2Ugc3VwcGxlbWVudCB3YXMgaW5jbHVkZWQgaW4gdGhpcyBwcmljZS4gVGhlIC0tPgo8IS0tIHB1YmxpY2F0aW9uIHdhcyBjcmVhdGVkIHVzaW5nIEFkb2JlIENTNS41IHNvZnR3YXJlIG9uIDQyIE1hY2ludG9zaCBkZXNrdG9wIGFuZCBsYXB0b3AgLS0+CjwhLS0gY29tcHV0ZXJzLiAtLT4KPCEtLSBQSE9UT0dSQVBIWTogUGlubmFjbGUgc3RhZmYgcGhvdG9ncmFwaGVycyBzaG90IGRpZ2l0YWwgcGhvdG9zIHVzaW5nIGZvdXIgTmlrb24gRDcwcywgLS0+CjwhLS0gdHdvIE5pa29uIEQ4MHMgYW5kIG9uZSBOaWtvbiBENDAuIFNwb3J0IGdyb3VwIHBob3RvcyB3ZXJlIHNob3QgYnkgUHJlc3RpZ2UgUG9ydHJhaXRzLCAtLT4KPCEtLSBhbmQgY2x1YiBhbmQgZ3JvdXAgcGhvdG9zIHdlcmUgc2hvdCBieSBib3RoIFByZXN0aWdlIFBvcnRyYWl0cyBhbmQgUGlubmFjbGUgeWVhcmJvb2sgc3RhZmYgLS0+CjwhLS0gcGhvdG9ncmFwaGVycy4gU29tZSBzdWJtaXR0ZWQgcGhvdG9zIGFwcGVhciB0aHJvdWdob3V0IHRoZSBib29rIGFzIHdlbGwuIC0tPgo8IS0tIEVESVRPUlPigJkgTk9URTogKEEgc3BlY2lhbCBub3RlIGZyb20gdGhlIGNvLWVkaXRvcnMtaW4tY2hpZWYgd2FzIGluY2x1ZGVkIGhlcmUuIFRoZSB5ZWFyYm9vayAtLT4KPCEtLSBzdGFmZiBwaG90byB3aXRoIG5hbWVzIGFuZCBzdGFmZiBwb3NpdGlvbnMgd2FzIGluY2x1ZGVkIG9uIHRoZSBzcHJlYWQgd2l0aCB0aGUgY29sb3Bob24uKSAtLT4KCjwhLS1jaGFwdGVyOmVuZDoxMl9jb2xvcGhvbi5SbWQtLT4KCgojIFJlZmVyZW5jZXMgey19CgoKPCEtLWNoYXB0ZXI6ZW5kOjEzX3JlZmVyZW5jZXMuUm1kLS0+Cgo=